Bookmark folder editing

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-09-24 18:15:49 +02:00
parent 49ec95b8f6
commit 2b6de423d5
10 changed files with 269 additions and 11 deletions

View file

@ -27,6 +27,7 @@ import NavPanel from 'src/components/nav_panel/nav_panel.vue'
import AnnouncementsPage from 'components/announcements_page/announcements_page.vue' import AnnouncementsPage from 'components/announcements_page/announcements_page.vue'
import QuotesTimeline from '../components/quotes_timeline/quotes_timeline.vue' import QuotesTimeline from '../components/quotes_timeline/quotes_timeline.vue'
import BookmarkFolders from '../components/bookmark_folders/bookmark_folders.vue' import BookmarkFolders from '../components/bookmark_folders/bookmark_folders.vue'
import BookmarkFolderEdit from '../components/bookmark_folder_edit/bookmark_folder_edit.vue'
export default (store) => { export default (store) => {
const validateAuthenticatedRoute = (to, from, next) => { const validateAuthenticatedRoute = (to, from, next) => {
@ -89,7 +90,9 @@ export default (store) => {
{ name: 'lists-new', path: '/lists/new', component: ListsEdit }, { name: 'lists-new', path: '/lists/new', component: ListsEdit },
{ name: 'edit-navigation', path: '/nav-edit', component: NavPanel, props: () => ({ forceExpand: true, forceEditMode: true }), beforeEnter: validateAuthenticatedRoute }, { name: 'edit-navigation', path: '/nav-edit', component: NavPanel, props: () => ({ forceExpand: true, forceEditMode: true }), beforeEnter: validateAuthenticatedRoute },
{ name: 'bookmark-folders', path: '/bookmark_folders', component: BookmarkFolders }, { name: 'bookmark-folders', path: '/bookmark_folders', component: BookmarkFolders },
{ name: 'bookmark-folder', path: '/bookmarks/:id', component: BookmarkTimeline } { name: 'bookmark-folder-new', path: '/bookmarks/new-folder', component: BookmarkFolderEdit },
{ name: 'bookmark-folder', path: '/bookmarks/:id', component: BookmarkTimeline },
{ name: 'bookmark-folder-edit', path: '/bookmarks/:id/edit', component: BookmarkFolderEdit }
] ]
if (store.state.instance.pleromaChatMessagesAvailable) { if (store.state.instance.pleromaChatMessagesAvailable) {

View file

@ -10,7 +10,12 @@ library.add(
const BookmarkFolderCard = { const BookmarkFolderCard = {
props: [ props: [
'folder' 'folder'
] ],
computed: {
firstLetter () {
return this.folder.name[0]
}
}
} }
export default BookmarkFolderCard export default BookmarkFolderCard

View file

@ -4,10 +4,28 @@
:to="{ name: 'bookmark-folder', params: { id: folder.id } }" :to="{ name: 'bookmark-folder', params: { id: folder.id } }"
class="bookmark-folder-name" class="bookmark-folder-name"
> >
{{ folder.name }} <img
v-if="folder.emoji_url"
class="iconEmoji iconEmoji-image"
:src="folder.emoji_url"
:alt="folder.emoji"
:title="folder.emoji"
>
<span
v-else-if="folder.emoji"
class="iconEmoji"
>
<span>
{{ folder.emoji }}
</span>
</span>
<span
v-else-if="firstLetter"
class="icon iconLetter fa-scale-110"
>{{ firstLetter }}</span>{{ folder.name }}
</router-link> </router-link>
<router-link <router-link
:to="{ name: 'bookmark-folder' /* -edit' */, params: { id: folder.id } }" :to="{ name: 'bookmark-folder-edit', params: { id: folder.id } }"
class="button-folder-edit" class="button-folder-edit"
> >
<FAIcon <FAIcon
@ -27,6 +45,35 @@
.bookmark-folder-name { .bookmark-folder-name {
flex-grow: 1; flex-grow: 1;
.iconLetter, .iconEmoji {
margin-right: 0.5em;
}
.iconLetter {
height: 2.5rem;
width: 2.5rem;
font-size: 1.5rem;
}
.iconEmoji {
display: inline-block;
text-align: center;
object-fit: contain;
vertical-align: middle;
height: 2.5em;
width: 2.5em;
> span {
font-size: 1.5rem;
line-height: 2.5rem;
}
}
img.iconEmoji {
padding: 0.25em;
box-sizing: border-box;
}
} }
.bookmark-folder-name, .bookmark-folder-name,

View file

@ -0,0 +1,65 @@
import apiService from '../../services/api/api.service'
const BookmarkFolderEdit = {
data () {
return {
name: '',
nameDraft: '',
emoji: '',
emojiUrl: null,
emojiDraft: '',
emojiUrlDraft: null,
reallyDelete: false
}
},
created () {
if (!this.id) return
const credentials = this.$store.state.users.currentUser.credentials
apiService.fetchBookmarkFolders({ credentials })
.then((folders) => {
const folder = folders.find(folder => folder.id === this.id)
if (!folder) return
this.nameDraft = this.name = folder.name
this.emojiDraft = this.emoji = folder.emoji
this.emojiUrlDraft = this.emojiUrl = folder.emoji_url
})
},
computed: {
id () {
return this.$route.params.id
}
},
methods: {
updateFolder () {
this.$store.dispatch('setBookmarkFolder', { folderId: this.id, name: this.nameDraft, emoji: this.emojiDraft })
.then((folder) => {
this.nameDraft = this.name = folder.name
this.emojiDraft = this.emoji = folder.emoji
this.emojiUrlDraft = this.emojiUrl = folder.emoji_url
})
},
createFolder () {
this.$store.dispatch('createBookmarkFolder', { name: this.nameDraft, emoji: this.emojiDraft })
.then((folder) => {
return folder.id
})
.then((folderId) => {
this.$router.push({ name: 'bookmark-folders' })
})
.catch((e) => {
this.$store.dispatch('pushGlobalNotice', {
messageKey: 'bookmark_folders.error',
messageArgs: [e.message],
level: 'error'
})
})
},
deleteFolder () {
this.$store.dispatch('deleteBookmarkFolder', { folderId: this.id })
this.$router.push({ name: 'bookmark-folders' })
}
}
}
export default BookmarkFolderEdit

View file

@ -0,0 +1,125 @@
<template>
<div class="panel-default panel BookmarkFolderEdit">
<div
ref="header"
class="panel-heading folder-edit-heading"
>
<button
class="button-unstyled go-back-button"
@click="$router.back"
>
<FAIcon
size="lg"
icon="chevron-left"
/>
</button>
<div class="title">
<i18n-t
v-if="id"
keypath="bookmark_folders.editing_folder"
>
<template #folderName>
{{ name }}
</template>
</i18n-t>
<i18n-t
v-else
keypath="bookmark_folders.creating_folder"
/>
</div>
</div>
<div class="panel-body">
<div class="input-wrap">
<label for="folder-edit-title">{{ $t('bookmark_folders.name') }}</label>
{{ ' ' }}
<input
id="folder-edit-title"
ref="name"
v-model="nameDraft"
class="input"
>
<button
v-if="id"
class="btn button-default follow-button"
@click="updateFolder"
>
{{ $t('bookmark_folders.update_folder') }}
</button>
</div>
</div>
<div class="panel-footer">
<span class="spacer" />
<button
v-if="!id"
class="btn button-default footer-button"
@click="createFolder"
>
{{ $t('bookmark_folders.create') }}
</button>
<button
v-else-if="!reallyDelete"
class="btn button-default footer-button"
@click="reallyDelete = true"
>
{{ $t('bookmark_folders.delete') }}
</button>
<template v-else>
{{ $t('bookmark_folders.really_delete') }}
<button
class="btn button-default footer-button"
@click="deleteFolder"
>
{{ $t('general.yes') }}
</button>
<button
class="btn button-default footer-button"
@click="reallyDelete = false"
>
{{ $t('general.no') }}
</button>
</template>
</div>
</div>
</template>
<script src="./bookmark_folder_edit.js"></script>
<style lang="scss">
.BookmarkFolderEdit {
--panel-body-padding: 0.5em;
overflow: hidden;
display: flex;
flex-direction: column;
.folder-edit-heading {
grid-template-columns: auto minmax(50%, 1fr);
}
.panel-body {
display: flex;
flex-direction: column;
overflow: hidden;
}
.go-back-button {
text-align: center;
line-height: 1;
height: 100%;
align-self: start;
width: var(--__panel-heading-height-inner);
}
.btn {
margin: 0 0.5em;
}
.panel-footer {
grid-template-columns: minmax(10%, 1fr);
.footer-button {
min-width: 9em;
}
}
}
</style>

View file

@ -5,7 +5,7 @@
{{ $t('nav.bookmark_folders') }} {{ $t('nav.bookmark_folders') }}
</div> </div>
<router-link <router-link
:to="{ name: 'bookmark-folders' /* 'new' */ }" :to="{ name: 'bookmark-folder-new' }"
class="button-default btn new-folder-button" class="button-default btn new-folder-button"
> >
{{ $t("bookmark_folders.new") }} {{ $t("bookmark_folders.new") }}

View file

@ -137,5 +137,10 @@
font-size: 1.5rem; font-size: 1.5rem;
} }
} }
img.iconEmoji {
padding: 0.25rem;
box-sizing: border-box;
}
} }
</style> </style>

View file

@ -1409,7 +1409,15 @@
"tooltip": "This domain contains non-ascii characters." "tooltip": "This domain contains non-ascii characters."
}, },
"bookmark_folders": { "bookmark_folders": {
"create": "Create folder",
"creating_folder": "Creating bookmark folder",
"delete": "Delete folder",
"editing_folder": "Editing folder {folderName}",
"error": "Error manipulating bookmark folders: {0}",
"name": "Folder name",
"new": "New Folder", "new": "New Folder",
"select_folder": "Select bookmark folder" "really_delete": "Do you really want to delete the folder?",
"select_folder": "Select bookmark folder",
"update_folder": "Save changes"
} }
} }

View file

@ -8,10 +8,10 @@ export const mutations = {
setBookmarkFolders (state, value) { setBookmarkFolders (state, value) {
state.allFolders = value state.allFolders = value
}, },
setBookmarkFolder (state, { folderId, name, emoji, emojiUrl }) { setBookmarkFolder (state, { id, name, emoji, emojiUrl }) {
const entry = find(state.allFolders, { id: name }) const entry = find(state.allFolders, { id })
if (!entry) { if (!entry) {
state.allFolders.push({ id: folderId, name, emoji, emojiUrl }) state.allFolders.push({ id, name, emoji, emojiUrl })
} else { } else {
entry.name = name entry.name = name
entry.emoji = emoji entry.emoji = emoji

View file

@ -1927,9 +1927,9 @@ const updateBookmarkFolder = ({ folderId, name, emoji, credentials }) => {
return fetch(url, { return fetch(url, {
headers, headers,
method: 'PUT', method: 'PATCH',
body: JSON.stringify({ name, emoji }) body: JSON.stringify({ name, emoji })
}) }).then((data) => data.json())
} }
const deleteBookmarkFolder = ({ folderId, credentials }) => { const deleteBookmarkFolder = ({ folderId, credentials }) => {