commit: faefd05c03d20a892a47c27550fe6e23978993c7
parent b4f4b370d406faf69be5c414ce394b608d8792f5
Author: Henry Jameson <me@hjkos.com>
Date: Wed, 17 Aug 2022 20:21:10 +0300
create new list UI
Diffstat:
8 files changed, 61 insertions(+), 198 deletions(-)
diff --git a/src/boot/routes.js b/src/boot/routes.js
@@ -80,6 +80,7 @@ export default (store) => {
{ name: 'lists', path: '/lists', component: Lists },
{ name: 'lists-timeline', path: '/lists/:id', component: ListsTimeline },
{ name: 'lists-edit', path: '/lists/:id/edit', component: ListsEdit },
+ { name: 'lists-edit', path: '/lists/new', component: ListsEdit },
{ name: 'edit-navigation', path: '/nav-edit', component: NavPanel, props: () => ({ forceExpand: true, forceEditMode: true }), beforeEnter: validateAuthenticatedRoute }
]
diff --git a/src/components/lists/lists.js b/src/components/lists/lists.js
@@ -1,5 +1,4 @@
import ListsCard from '../lists_card/lists_card.vue'
-import ListsNew from '../lists_new/lists_new.vue'
const Lists = {
data () {
@@ -8,8 +7,7 @@ const Lists = {
}
},
components: {
- ListsCard,
- ListsNew
+ ListsCard
},
computed: {
lists () {
diff --git a/src/components/lists/lists.vue b/src/components/lists/lists.vue
@@ -1,21 +1,15 @@
<template>
- <div v-if="isNew">
- <ListsNew @cancel="cancelNewList" />
- </div>
- <div
- v-else
- class="settings panel panel-default"
- >
+ <div class="Lists panel panel-default">
<div class="panel-heading">
<div class="title">
{{ $t('lists.lists') }}
</div>
- <button
- class="button-default"
- @click="newList"
+ <router-link
+ :to="{ name: 'lists-edit' }"
+ class="button-default btn new-list-button"
>
{{ $t("lists.new") }}
- </button>
+ </router-link>
</div>
<div class="panel-body">
<ListsCard
@@ -29,3 +23,11 @@
</template>
<script src="./lists.js"></script>
+
+<style lang="scss">
+.Lists {
+ .new-list-button {
+ padding: 0 0.5em;
+ }
+}
+</style>
diff --git a/src/components/lists_edit/lists_edit.js b/src/components/lists_edit/lists_edit.js
@@ -36,6 +36,7 @@ const ListsNew = {
}
},
created () {
+ if (!this.id) return
this.$store.dispatch('fetchList', { listId: this.id })
.then(() => {
this.title = this.findListTitle(this.id)
@@ -71,19 +72,19 @@ const ListsNew = {
},
toggleRemoveMember (user) {
if (this.removedUserIds.has(user.id)) {
- this.addUser(user)
+ this.id && this.addUser(user)
this.removedUserIds.delete(user.id)
} else {
- this.removeUser(user.id)
+ this.id && this.removeUser(user.id)
this.removedUserIds.add(user.id)
}
},
toggleAddFromSearch (user) {
if (this.addedUserIds.has(user.id)) {
- this.removeUser(user.id)
+ this.id && this.removeUser(user.id)
this.addedUserIds.delete(user.id)
} else {
- this.addUser(user)
+ this.id && this.addUser(user)
this.addedUserIds.add(user.id)
}
},
@@ -115,6 +116,25 @@ const ListsNew = {
this.title = this.findListTitle(this.id)
})
},
+ createList () {
+ this.$store.dispatch('createList', { title: this.titleDraft })
+ .then((list) => {
+ return this
+ .$store
+ .dispatch('setListAccounts', { listId: list.id, accountIds: [...this.addedUserIds] })
+ .then(() => list.id)
+ })
+ .then((listId) => {
+ this.$router.push({ name: 'lists-timeline', params: { id: listId } })
+ })
+ .catch((e) => {
+ this.$store.dispatch('pushGlobalNotice', {
+ messageKey: 'lists.error',
+ messageArgs: [e.message],
+ level: 'error'
+ })
+ })
+ },
deleteList () {
this.$store.dispatch('deleteList', { listId: this.id })
this.$router.push({ name: 'lists' })
diff --git a/src/components/lists_edit/lists_edit.vue b/src/components/lists_edit/lists_edit.vue
@@ -15,12 +15,17 @@
</button>
<div class="title">
<i18n-t
+ v-if="id"
keypath="lists.editing_list"
>
<template #listTitle>
{{ title }}
</template>
</i18n-t>
+ <i18n-t
+ v-else
+ keypath="lists.creating_list"
+ />
</div>
</div>
<div class="panel-body">
@@ -33,6 +38,7 @@
v-model="titleDraft"
>
<button
+ v-if="id"
class="btn button-default follow-button"
@click="updateListTitle"
>
@@ -44,6 +50,7 @@
:scrollable-tabs="true"
>
<div
+ v-if="id || addedUserIds.size > 0"
:label="$t('lists.manage_members')"
class="members-list"
>
@@ -122,8 +129,15 @@
<div class="panel-footer">
<span class="spacer" />
<button
- v-if="!reallyDelete"
- class="btn button-default delete-button"
+ v-if="!id"
+ class="btn button-default footer-button"
+ @click="createList"
+ >
+ {{ $t('lists.create') }}
+ </button>
+ <button
+ v-else-if="!reallyDelete"
+ class="btn button-default footer-button"
@click="reallyDelete = true"
>
{{ $t('lists.delete') }}
@@ -131,13 +145,13 @@
<template v-else>
{{ $t('lists.really_delete') }}
<button
- class="btn button-default delete-button"
+ class="btn button-default footer-button"
@click="deleteList"
>
{{ $t('general.yes') }}
</button>
<button
- class="btn button-default delete-button"
+ class="btn button-default footer-button"
@click="reallyDelete = false"
>
{{ $t('general.no') }}
@@ -206,7 +220,7 @@
.panel-footer {
grid-template-columns: minmax(10%, 1fr);
- .delete-button {
+ .footer-button {
min-width: 9em;
}
}
diff --git a/src/components/lists_new/lists_new.js b/src/components/lists_new/lists_new.js
@@ -1,79 +0,0 @@
-import { mapState, mapGetters } from 'vuex'
-import BasicUserCard from '../basic_user_card/basic_user_card.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
-import ListsUserSearch from '../lists_user_search/lists_user_search.vue'
-import { library } from '@fortawesome/fontawesome-svg-core'
-import {
- faSearch,
- faChevronLeft
-} from '@fortawesome/free-solid-svg-icons'
-
-library.add(
- faSearch,
- faChevronLeft
-)
-
-const ListsNew = {
- components: {
- BasicUserCard,
- UserAvatar,
- ListsUserSearch
- },
- data () {
- return {
- title: '',
- userIds: [],
- selectedUserIds: []
- }
- },
- computed: {
- users () {
- return this.userIds.map(userId => this.findUser(userId))
- },
- selectedUsers () {
- return this.selectedUserIds.map(userId => this.findUser(userId))
- },
- ...mapState({
- currentUser: state => state.users.currentUser
- }),
- ...mapGetters(['findUser'])
- },
- methods: {
- goBack () {
- this.$emit('cancel')
- },
- onInput () {
- this.search(this.query)
- },
- selectUser (user) {
- if (this.selectedUserIds.includes(user.id)) {
- this.removeUser(user.id)
- } else {
- this.addUser(user)
- }
- },
- isSelected (user) {
- return this.selectedUserIds.includes(user.id)
- },
- addUser (user) {
- this.selectedUserIds.push(user.id)
- },
- removeUser (userId) {
- this.selectedUserIds = this.selectedUserIds.filter(id => id !== userId)
- },
- onResults (results) {
- this.userIds = results
- },
- createList () {
- // the API has two different endpoints for "creating a list with a name"
- // and "updating the accounts on the list".
- this.$store.dispatch('createList', { title: this.title })
- .then((list) => {
- this.$store.dispatch('setListAccounts', { listId: list.id, accountIds: this.selectedUserIds })
- this.$router.push({ name: 'lists-timeline', params: { listId: list.id } })
- })
- }
- }
-}
-
-export default ListsNew
diff --git a/src/components/lists_new/lists_new.vue b/src/components/lists_new/lists_new.vue
@@ -1,95 +0,0 @@
-<template>
- <div class="panel-default panel list-new">
- <div
- ref="header"
- class="panel-heading"
- >
- <button
- class="button-unstyled go-back-button"
- @click="goBack"
- >
- <FAIcon
- size="lg"
- icon="chevron-left"
- />
- </button>
- </div>
- <div class="input-wrap">
- <input
- ref="title"
- v-model="title"
- :placeholder="$t('lists.title')"
- >
- </div>
-
- <div class="member-list">
- <div
- v-for="user in selectedUsers"
- :key="user.id"
- class="member"
- >
- <BasicUserCard
- :user="user"
- :class="isSelected(user) ? 'selected' : ''"
- @click.capture.prevent="selectUser(user)"
- />
- </div>
- </div>
- <ListsUserSearch
- @results="onResults"
- />
- <div
- v-for="user in users"
- :key="user.id"
- class="member"
- >
- <BasicUserCard
- :user="user"
- :class="isSelected(user) ? 'selected' : ''"
- @click.capture.prevent="selectUser(user)"
- />
- </div>
-
- <button
- :disabled="title && title.length === 0"
- class="btn button-default"
- @click="createList"
- >
- {{ $t('lists.create') }}
- </button>
- </div>
-</template>
-
-<script src="./lists_new.js"></script>
-
-<style lang="scss">
-@import '../../_variables.scss';
-
-.list-new {
- .search-icon {
- margin-right: 0.3em;
- }
-
- .member-list {
- padding-bottom: 0.7rem;
- }
-
- .basic-user-card:hover,
- .basic-user-card.selected {
- cursor: pointer;
- background-color: var(--selectedPost, $fallback--lightBg);
- }
-
- .go-back-button {
- text-align: center;
- line-height: 1;
- height: 100%;
- align-self: start;
- width: var(--__panel-heading-height-inner);
- }
-
- .btn {
- margin: 0.5em;
- }
-}
-</style>
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -991,8 +991,10 @@
"add_to_list": "Add to list",
"is_in_list": "Already in list",
"editing_list": "Editing list {listTitle}",
+ "creating_list": "Creating new list",
"update_title": "Save Title",
- "really_delete": "Really delete list?"
+ "really_delete": "Really delete list?",
+ "error": "Error manipulating lists: {0}"
},
"file_type": {
"audio": "Audio",