1
0
mirror of https://github.com/aquatix/digimarks.git synced 2025-12-06 20:55:10 +01:00

2 Commits

Author SHA1 Message Date
36370cfad4 Use Javascript camelCase in variables 2025-06-16 22:38:54 +02:00
63a86a7090 Edit/Add bookmark modal 2025-06-16 22:32:43 +02:00
3 changed files with 96 additions and 70 deletions

View File

@@ -322,6 +322,7 @@ th, td {
/*padding: 1em;*/
}
[data-theme='nebula'] :modal,
[data-theme='nebula'] .card,
[data-theme='nebula'] button,
[data-theme='nebula'] .button,
@@ -329,6 +330,7 @@ th, td {
[data-theme='nebula'] select,
[data-theme='nebula'] textarea,
[data-theme='nebula'] table,
[data-theme='nebula-dark'] :modal,
[data-theme='nebula-dark'] .card,
[data-theme='nebula-dark'] button,
[data-theme='nebula-dark'] .button,
@@ -427,6 +429,16 @@ th, td {
}
/** Modal, e.g. for showing info or filling in a form; on top of the other content */
:modal {
color: var(--text-color);
background-color: var(--background-color);
border: 2px solid var(--border-color);
border-radius: var(--border-radius);
}
/** Footer */
footer {

View File

@@ -1,24 +1,22 @@
document.addEventListener('alpine:init', () => {
Alpine.store('digimarks', {
/** Main digimarks application, state etc */
// userKey: Alpine.$persist(0).as('userKey'),
userKey: -1,
/* cache consists of cache[userKey] = {'bookmarks': [], 'tags': [], ??} */
cache: Alpine.$persist({}).as('cache'),
bookmarks: [],
/* Bookmark that is being edited, used to fill the form etc */
bookmark_to_edit: null,
/* nebula (dropshadows), bbs (monospace, right lines), silo (like bbs but dark) ?? */
/* nebula (drop-shadows), bbs (monospace, right lines), silo (like bbs but dark) ?? */
themes: ['nebula', 'nebula-dark', 'bbs', 'silo'],
theme: Alpine.$persist('nebula').as('theme'),
show_bookmarks: Alpine.$persist(true).as('show_bookmarks'),
show_bookmarks_list: Alpine.$persist(true).as('show_bookmarks_list'),
show_bookmarks_cards: Alpine.$persist(false).as('show_bookmarks_cards'),
show_tags: Alpine.$persist(false).as('show_tags'),
showBookmarks: Alpine.$persist(true).as('showBookmarks'),
showBookmarksList: Alpine.$persist(true).as('showBookmarksList'),
showBookmarksCards: Alpine.$persist(false).as('showBookmarksCards'),
showTags: Alpine.$persist(false).as('showTags'),
/* Bookmark that is being edited, used to fill the form, etc. */
bookmarkToEdit: Alpine.$persist(null).as('bookmarkToEdit'),
/* Loading indicator */
loading: false,
@@ -26,15 +24,15 @@ document.addEventListener('alpine:init', () => {
/* Search filter */
search: '',
/* Show bookmarks with this tag/these tags */
tags_filter: [],
tagsFilter: [],
/* Hide bookmarks with these tags */
tags_to_hide: Alpine.$persist([]).as('tags_to_hide'),
tagsToHide: Alpine.$persist([]).as('tags_to_hide'),
/* Sort on ~ */
sort_title_asc: Alpine.$persist(false).as('sort_title_asc'),
sort_title_desc: Alpine.$persist(false).as('sort_title_desc'),
sort_created_asc: Alpine.$persist(false).as('sort_created_asc'),
sort_created_desc: Alpine.$persist(false).as('sort_created_desc'),
sortTitleAsc: Alpine.$persist(false).as('sortTitleAsc'),
sortTitleDesc: Alpine.$persist(false).as('sortTitleDesc'),
sortCreatedAsc: Alpine.$persist(false).as('sortCreatedAsc'),
sortCreatedDesc: Alpine.$persist(false).as('sortCreatedDesc'),
async init() {
/** Initialise the application after loading */
@@ -79,14 +77,14 @@ document.addEventListener('alpine:init', () => {
this.cache[this.userKey] = {'bookmarks': [], 'latest_changes': {}};
}
let latest_status_response = await fetch('/api/v1/' + this.userKey + '/latest_changes/');
let latest_status_result = await latest_status_response.json();
let should_fetch = false;
let latest_modification_in_cache = this.cache[this.userKey].latest_changes.latest_modification || "0000-00-00";
should_fetch = latest_status_result.latest_modification > latest_modification_in_cache;
this.cache[this.userKey].latest_changes = latest_status_result;
let latestStatusResponse = await fetch('/api/v1/' + this.userKey + '/latest_changes/');
let latestStatusResult = await latestStatusResponse.json();
let shouldFetch = false;
let latestModificationInCache = this.cache[this.userKey].latest_changes.latest_modification || "0000-00-00";
shouldFetch = latestStatusResult.latest_modification > latestModificationInCache;
this.cache[this.userKey].latest_changes = latestStatusResult;
if (!should_fetch) {
if (!shouldFetch) {
console.log('Cache is up-to-date');
this.loading = false;
return;
@@ -98,8 +96,8 @@ document.addEventListener('alpine:init', () => {
/* Cache the bookmarks to Local Storage */
this.cache[this.userKey]['bookmarks'] = await response.json();
let tags_response = await fetch('/api/v1/' + this.userKey + '/tags/');
this.cache[this.userKey]['tags'] = await tags_response.json();
let tagsResponse = await fetch('/api/v1/' + this.userKey + '/tags/');
this.cache[this.userKey]['tags'] = await tagsResponse.json();
/* Filter bookmarks by (blacklisted) tags */
await this.filterBookmarksByTags();
@@ -121,14 +119,14 @@ document.addEventListener('alpine:init', () => {
/* Filter away bookmarks with a tag on the 'blacklist' */
/* First make a shallow copy of all bookmarks */
let prefiltered_bookmarks = [...this.cache[this.userKey]['bookmarks']] || [];
if (this.tags_to_hide.length > 0) {
let prefilteredBookmarks = [...this.cache[this.userKey]['bookmarks']] || [];
if (this.tagsToHide.length > 0) {
console.log('Filtering away bookmarks containing blacklisted tags');
this.bookmarks = prefiltered_bookmarks.filter(
i => !this.hasTag(i.tag_list, this.tags_to_hide)
this.bookmarks = prefilteredBookmarks.filter(
i => !this.hasTag(i.tag_list, this.tagsToHide)
)
} else {
this.bookmarks = prefiltered_bookmarks;
this.bookmarks = prefilteredBookmarks;
}
this.sortBookmarks();
},
@@ -153,27 +151,27 @@ document.addEventListener('alpine:init', () => {
sortBookmarks() {
/* Sort the bookmarks according to the setting */
if (this.sort_title_asc) {
if (this.sortTitleAsc) {
this.bookmarks.sort((a, b) => a.title.localeCompare(b.title));
} else if (this.sort_title_desc) {
} else if (this.sortTitleDesc) {
this.bookmarks.sort((a, b) => b.title.localeCompare(a.title));
} else if (this.sort_created_asc) {
} else if (this.sortCreatedAsc) {
this.bookmarks.sort((a, b) => a.created_date.localeCompare(b.created_date));
} else if (this.sort_created_desc) {
} else if (this.sortCreatedDesc) {
this.bookmarks.sort((a, b) => b.created_date.localeCompare(a.created_date));
}
},
async sortAlphabetically(order = 'asc') {
/* Sort the bookmarks (reverse) alphabetically, based on 'asc' or 'desc' */
this.loading = true;
this.sort_created_asc = false;
this.sort_created_desc = false;
this.sort_title_asc = false;
this.sort_title_desc = false;
this.sortCreatedAsc = false;
this.sortCreatedDesc = false;
this.sortTitleAsc = false;
this.sortTitleDesc = false;
if (order === 'desc') {
this.sort_title_desc = true;
this.sortTitleDesc = true;
} else {
this.sort_title_asc = true;
this.sortTitleAsc = true;
}
this.sortBookmarks();
this.loading = false;
@@ -181,14 +179,14 @@ document.addEventListener('alpine:init', () => {
async sortCreated(order = 'asc') {
/* Sort the bookmarks (reverse) chronologically, based on 'asc' or 'desc' */
this.loading = true;
this.sort_created_asc = false;
this.sort_created_desc = false;
this.sort_title_asc = false;
this.sort_title_desc = false;
this.sortCreatedAsc = false;
this.sortCreatedDesc = false;
this.sortTitleAsc = false;
this.sortTitleDesc = false;
if (order === 'desc') {
this.sort_created_desc = true;
this.sortCreatedDesc = true;
} else {
this.sort_created_asc = true;
this.sortCreatedAsc = true;
}
this.sortBookmarks();
this.loading = false;
@@ -196,22 +194,28 @@ document.addEventListener('alpine:init', () => {
async toggleTagPage() {
/* Show or hide the tag page instead of the bookmarks */
console.log('Toggle tag page');
this.show_bookmarks = !this.show_bookmarks;
this.show_tags = !this.show_bookmarks;
this.showBookmarks = !this.showBookmarks;
this.showTags = !this.showBookmarks;
},
async toggleListOrGrid() {
/* Toggle between 'list' or 'grid' (cards) view */
this.show_bookmarks_list = !this.show_bookmarks_list;
this.show_bookmarks_cards = !this.show_bookmarks_list;
this.showBookmarksList = !this.showBookmarksList;
this.showBookmarksCards = !this.showBookmarksList;
},
async startAddingBookmark() {
/* Open 'add bookmark' page */
console.log('Start adding bookmark');
this.bookmark_to_edit = {
this.bookmarkToEdit = {
'url': ''
}
// this.show_bookmark_details = true;
const editFormDialog = document.getElementById("editFormDialog");
editFormDialog.showModal();
},
async saveBookmark() {
console.log('Saving bookmark');
// this.show_bookmark_details = false;
},
async addBookmark() {
/* Post new bookmark to the backend */

View File

@@ -12,7 +12,7 @@
<li><h1>digimarks</h1></li>
<li>
<button x-data @click="$store.digimarks.toggleTagPage()"
:class="$store.digimarks.show_tags && 'active'">tags
:class="$store.digimarks.showTags && 'active'">tags
</button>
</li>
<li>
@@ -28,29 +28,28 @@
</header>
<main>
<section x-cloak x-show="$store.digimarks.show_bookmarks && !$store.digimarks.bookmark_to_edit"
x-transition.opacity>
<section x-cloak x-show="$store.digimarks.showBookmarks" x-transition.opacity>
<h1 x-bind:title="$store.digimarks.userKey">Bookmarks</h1>
<p>
<button @click="$store.digimarks.sortAlphabetically()"
:class="$store.digimarks.sort_title_asc && 'active'">a-z &darr;
:class="$store.digimarks.sortTitleAsc && 'active'">a-z &darr;
</button>
<button @click="$store.digimarks.sortAlphabetically('desc')"
:class="$store.digimarks.sort_title_desc && 'active'">z-a &uarr;
:class="$store.digimarks.sortTitleDesc && 'active'">z-a &uarr;
</button>
<button @click="$store.digimarks.sortCreated()"
:class="$store.digimarks.sort_created_asc && 'active'">date &darr;
:class="$store.digimarks.sortCreatedAsc && 'active'">date &darr;
</button>
<button @click="$store.digimarks.sortCreated('desc')"
:class="$store.digimarks.sort_created_desc && 'active'">date &uarr;
:class="$store.digimarks.sortCreatedDesc && 'active'">date &uarr;
</button>
<button @click="$store.digimarks.toggleListOrGrid()"
:class="$store.digimarks.show_bookmarks_cards && 'active'">list or grid
:class="$store.digimarks.showBookmarksCards && 'active'">list or grid
</button>
</p>
<table x-cloak x-show="$store.digimarks.show_bookmarks_list">
<table x-cloak x-show="$store.digimarks.showBookmarksList">
<thead>
<tr>
<th colspan="2">&nbsp;</th>
@@ -92,7 +91,7 @@
</template>
</ul>
#}
<section x-cloak x-show="$store.digimarks.show_bookmarks_cards" class="cards">
<section x-cloak x-show="$store.digimarks.showBookmarksCards" class="cards">
<template x-for="bookmark in $store.digimarks.filteredBookmarks" :key="bookmark.id">
<div class="card">
<div class="card-body">
@@ -123,8 +122,7 @@
</section>
</section>
<section x-cloak x-show="$store.digimarks.show_tags && !$store.digimarks.bookmark_to_edit"
x-transition.opacity>
<section x-cloak x-show="$store.digimarks.showTags" x-transition.opacity>
<h1>Tags</h1>
<table>
@@ -147,7 +145,13 @@
</table>
</section>
<section x-cloak x-show="$store.digimarks.bookmark_to_edit" x-transition.opacity>
<dialog x-cloak id="editFormDialog"
x-transition:enter="modal-enter"
x-transition:enter-start="modal-enter"
x-transition:enter-end="modal-enter-active"
x-transition:leave="modal-leave-active"
x-transition:leave-start="modal-enter-active"
x-transition:leave-end="modal-enter">
<h1>Add/Edit bookmark</h1>
{#
<div class="card-panel {{ theme.ERRORMESSAGE_BACKGROUND }}">
@@ -166,14 +170,20 @@
</span>
</div>
#}
<form>
<form method="dialog">
<input type="text" name="">
<label>
<input type="checkbox" name="strip" id="strip"/>
<span>Strip parameters from url (like <em>?utm_source=social</em> - can break the link!)</span>
</label>
<p>
<label>
<input type="checkbox" name="strip" id="strip"/>
<span>Strip parameters from url (like <em>?utm_source=social</em> - can break the link!)</span>
</label>
</p>
<div>
<button value="cancel">Cancel</button>
<button @click="$store.digimarks.saveBookmark()">Save</button>
</div>
</form>
</section>
</dialog>
</main>
</article>