add follow/unfollow to followed tags list

This commit is contained in:
FloatingGhost 2023-01-01 21:05:25 +00:00 committed by hynet-mel
parent 79d506e331
commit e095e22f2c
7 changed files with 86 additions and 30 deletions

View file

@ -1,10 +1,28 @@
<template> <template>
<div class="followed-tag-card"> <div class="followed-tag-card">
<h3> <span>
<router-link :to="{ name: 'tag-timeline', params: {tag: tag.name}}"> <router-link :to="{ name: 'tag-timeline', params: {tag: tag.name}}">
#{{ tag.name }} <span class="tag-link">#{{ tag.name }}</span>
</router-link> </router-link>
</h3> <span class="unfollow-tag">
<button
v-if="isFollowing"
class="button-default unfollow-tag-button"
:title="$t('user_card.unfollow_tag')"
@click="unfollowTag(tag.name)"
>
{{ $t('user_card.unfollow_tag') }}
</button>
<button
v-else
class="button-default follow-tag-button"
:title="$t('user_card.follow_tag')"
@click="followTag(tag.name)"
>
{{ $t('user_card.follow_tag') }}
</button>
</span>
</span>
</div> </div>
</template> </template>
@ -15,13 +33,45 @@ export default {
tag: { tag: {
type: Object, type: Object,
required: true required: true
}
}, },
},
// this is a hack to update the state of the button
// for some reason, List does not update on changes to the tag object
data: () => ({
isFollowing: true
}),
mounted () {
this.isFollowing = this.tag.following
},
methods: {
unfollowTag (tag) {
this.$store.dispatch('unfollowTag', tag)
this.isFollowing = false
},
followTag (tag) {
this.$store.dispatch('followTag', tag)
this.isFollowing = true
}
}
} }
</script> </script>
<style scoped> <style scoped>
.followed-tag-card { .followed-tag-card {
margin-left: 1rem; margin-left: 1rem;
} margin-top: 1rem;
margin-bottom: 1rem;
}
.unfollow-tag {
position: absolute;
right: 1rem;
}
.tag-link {
font-size: large;
}
.unfollow-tag-button, .follow-tag-button {
font-size: medium;
}
</style> </style>

View file

@ -52,6 +52,7 @@ const UserProfile = {
error: false, error: false,
userId: null, userId: null,
tab: 'statuses', tab: 'statuses',
followsTab: 'users',
footerRef: null, footerRef: null,
note: null, note: null,
noteLoading: false noteLoading: false
@ -176,6 +177,9 @@ const UserProfile = {
this.tab = tab this.tab = tab
this.$router.replace({ hash: `#${tab}` }) this.$router.replace({ hash: `#${tab}` })
}, },
onFollowsTabSwitch (tab) {
this.followsTab = tab
},
linkClicked ({ target }) { linkClicked ({ target }) {
if (target.tagName === 'SPAN') { if (target.tagName === 'SPAN') {
target = target.parentNode target = target.parentNode

View file

@ -106,8 +106,9 @@
:label="$t('user_card.followees')" :label="$t('user_card.followees')"
> >
<tab-switcher <tab-switcher
:active-tab="users" :active-tab="followsTab"
:render-only-focused="true" :render-only-focused="true"
:on-switch="onFollowsTabSwitch"
> >
<div <div
key="users" key="users"
@ -126,12 +127,14 @@
> >
<FollowedTagList <FollowedTagList
:user-id="userId" :user-id="userId"
:following="false"
:get-key="(item) => item.name" :get-key="(item) => item.name"
> >
<template #item="{item}"> <template #item="{item}">
<FollowedTagCard :tag="item" /> <FollowedTagCard :tag="item" />
</template> </template>
<template #empty>
{{ $t('user_card.not_following_any_hashtags')}}
</template>
</FollowedTagList> </FollowedTagList>
</div> </div>
</tab-switcher> </tab-switcher>

View file

@ -89,7 +89,7 @@ const withLoadMore = ({
const children = this.$slots const children = this.$slots
return ( return (
<div class="with-load-more"> <div class="with-load-more">
<WrappedComponent {...props}> <WrappedComponent {...props} >
{children} {children}
</WrappedComponent> </WrappedComponent>
<div class="with-load-more-footer"> <div class="with-load-more-footer">

View file

@ -1057,6 +1057,7 @@
"show_new": "Show new", "show_new": "Show new",
"socket_broke": "Realtime connection lost: CloseEvent code {0}", "socket_broke": "Realtime connection lost: CloseEvent code {0}",
"socket_reconnected": "Realtime connection established", "socket_reconnected": "Realtime connection established",
"follow_tag": "Follow hashtag",
"unfollow_tag": "Unfollow hashtag", "unfollow_tag": "Unfollow hashtag",
"up_to_date": "Up-to-date" "up_to_date": "Up-to-date"
}, },
@ -1179,6 +1180,9 @@
"unfollow_confirm_accept_button": "Yes, unfollow", "unfollow_confirm_accept_button": "Yes, unfollow",
"unfollow_confirm_cancel_button": "No, don't unfollow", "unfollow_confirm_cancel_button": "No, don't unfollow",
"unfollow_confirm_title": "Unfollow user", "unfollow_confirm_title": "Unfollow user",
"not_following_any_hashtags": "You are not following any hashtags",
"follow_tag": "Follow hashtag",
"unfollow_tag": "Unfollow hashtag",
"unmute": "Unmute", "unmute": "Unmute",
"unmute_progress": "Unmuting…", "unmute_progress": "Unmuting…",
"unsubscribe": "Unsubscribe" "unsubscribe": "Unsubscribe"

View file

@ -2,11 +2,18 @@ import { merge } from 'lodash'
const tags = { const tags = {
state: { state: {
// Contains key = id, value = number of trackers for this poll // Contains key = name, value = tag json
tags: {} tags: {}
}, },
getters: {
findTag: state => query => {
const result = state.tags[query]
return result
},
},
mutations: { mutations: {
setTag (state, { name, data }) { setTag (state, { name, data }) {
console.log("Setting", name, {...data})
state.tags[name] = data state.tags[name] = data
} }
}, },
@ -17,17 +24,17 @@ const tags = {
return tag return tag
}) })
}, },
followTag (store, tagName) { followTag ({ rootState, commit }, tagName) {
return store.rootState.api.backendInteractor.followHashtag({ tag: tagName }) return rootState.api.backendInteractor.followHashtag({ tag: tagName })
.then((resp) => { .then((resp) => {
store.commit('setTag', { name: tagName, data: resp }) commit('setTag', { name: tagName, data: resp })
return resp return resp
}) })
}, },
unfollowTag ({ rootState, commit }, tag) { unfollowTag ({ rootState, commit }, tagName) {
return rootState.api.backendInteractor.unfollowHashtag({ tag }) return rootState.api.backendInteractor.unfollowHashtag({ tag: tagName })
.then((resp) => { .then((resp) => {
commit('setTag', { name: tag, data: resp }) commit('setTag', { name: tagName, data: resp })
return resp return resp
}) })
} }

View file

@ -193,11 +193,6 @@ export const mutations = {
mergeOrAdd(state.users, state.usersObject, user) mergeOrAdd(state.users, state.usersObject, user)
}) })
}, },
addNewTags (state, tags) {
each(tags, (tag) => {
mergeOrAdd(state.tags, state.tagsObject, tag, 'name')
})
},
updateUserRelationship (state, relationships) { updateUserRelationship (state, relationships) {
relationships.forEach((relationship) => { relationships.forEach((relationship) => {
state.relationships[relationship.id] = relationship state.relationships[relationship.id] = relationship
@ -291,10 +286,6 @@ export const getters = {
const rel = id && state.relationships[id] const rel = id && state.relationships[id]
return rel || { id, loading: true } return rel || { id, loading: true }
}, },
findTag: state => query => {
const result = state.tagsObject[query]
return result
},
} }
export const defaultState = { export const defaultState = {
@ -433,7 +424,7 @@ const users = {
return rootState.api.backendInteractor.getFollowedHashtags({ pagination }) return rootState.api.backendInteractor.getFollowedHashtags({ pagination })
.then(({ data: tags, pagination }) => { .then(({ data: tags, pagination }) => {
commit('addNewTags', tags) each(tags, tag => commit('setTag', { name: tag.name, data: tag }))
commit('saveFollowedTagIds', { id, followedTagIds: tags.map(tag => tag.name) }) commit('saveFollowedTagIds', { id, followedTagIds: tags.map(tag => tag.name) })
commit('saveFollowedTagPagination', { id, pagination }) commit('saveFollowedTagPagination', { id, pagination })
return tags return tags
@ -477,9 +468,6 @@ const users = {
addNewUsers ({ commit }, users) { addNewUsers ({ commit }, users) {
commit('addNewUsers', users) commit('addNewUsers', users)
}, },
addNewTags ({ commit }, tags) {
commit('addNewTags', tags)
},
addNewStatuses (store, { statuses }) { addNewStatuses (store, { statuses }) {
const users = map(statuses, 'user') const users = map(statuses, 'user')
const retweetedUsers = compact(map(statuses, 'retweeted_status.user')) const retweetedUsers = compact(map(statuses, 'retweeted_status.user'))