aboutsummaryrefslogtreecommitdiff
path: root/src/components/lists_new
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/lists_new')
-rw-r--r--src/components/lists_new/lists_new.js79
-rw-r--r--src/components/lists_new/lists_new.vue95
2 files changed, 174 insertions, 0 deletions
diff --git a/src/components/lists_new/lists_new.js b/src/components/lists_new/lists_new.js
new file mode 100644
index 00000000..63dc28ad
--- /dev/null
+++ b/src/components/lists_new/lists_new.js
@@ -0,0 +1,79 @@
+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', { id: list.id, accountIds: this.selectedUserIds })
+ this.$router.push({ name: 'lists-timeline', params: { id: list.id } })
+ })
+ }
+ }
+}
+
+export default ListsNew
diff --git a/src/components/lists_new/lists_new.vue b/src/components/lists_new/lists_new.vue
new file mode 100644
index 00000000..4733bdde
--- /dev/null
+++ b/src/components/lists_new/lists_new.vue
@@ -0,0 +1,95 @@
+<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>