Merge remote-tracking branch 'upstream/develop' into shigusegubu
* upstream/develop: (24 commits) link interaction avatars to the user profile Use more clear explanation in the scope notice, make sure the hide button doesn't overlap with text in notice. use backendInteractor refactor api service functions using new helper clean up update favorite number earlier update status interaction upon retweet action response sync up favoritedBy with favorite/unfavorite action do not regenerate status object reduce needless calculation Move scope visibility notice to the status form, make it dismissible Revert "eliminate expandable prop in favor of inConversation" status attention doesn’t have relationship entities make it short fix wrong inlineExpanded expanded is always false, eliminate it eliminate expandable prop in favor of inConversation fix conversationId comparision bug using integer format Display additional scope description above the status form for mobile users. Update es.json ...
This commit is contained in:
commit
0084a63e41
22 changed files with 193 additions and 113 deletions
13
src/App.scss
13
src/App.scss
|
@ -648,6 +648,19 @@ nav {
|
|||
border-radius: var(--inputRadius, $fallback--inputRadius);
|
||||
}
|
||||
|
||||
.notice-dismissible {
|
||||
padding-right: 4rem;
|
||||
position: relative;
|
||||
|
||||
.dismiss {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: .5em;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes modal-background-fadein {
|
||||
from {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
|
|
16
src/App.vue
16
src/App.vue
|
@ -18,17 +18,19 @@
|
|||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div v-if="" class="container" id="content">
|
||||
<div class="sidebar-flexer mobile-hidden" v-if="!isMobileLayout">
|
||||
<div class="container" id="content">
|
||||
<div class="sidebar-flexer mobile-hidden">
|
||||
<div class="sidebar-bounds">
|
||||
<div class="sidebar-scroller">
|
||||
<div class="sidebar">
|
||||
<user-panel></user-panel>
|
||||
<nav-panel></nav-panel>
|
||||
<instance-specific-panel v-if="showInstanceSpecificPanel"></instance-specific-panel>
|
||||
<features-panel v-if="!currentUser && showFeaturesPanel"></features-panel>
|
||||
<who-to-follow-panel v-if="currentUser && suggestionsEnabled"></who-to-follow-panel>
|
||||
<notifications v-if="currentUser"></notifications>
|
||||
<div v-if="!isMobileLayout">
|
||||
<nav-panel></nav-panel>
|
||||
<instance-specific-panel v-if="showInstanceSpecificPanel"></instance-specific-panel>
|
||||
<features-panel v-if="!currentUser && showFeaturesPanel"></features-panel>
|
||||
<who-to-follow-panel v-if="currentUser && suggestionsEnabled"></who-to-follow-panel>
|
||||
<notifications v-if="currentUser"></notifications>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||
|
||||
const AvatarList = {
|
||||
props: ['users'],
|
||||
|
@ -9,6 +10,11 @@ const AvatarList = {
|
|||
},
|
||||
components: {
|
||||
UserAvatar
|
||||
},
|
||||
methods: {
|
||||
userProfileLink (user) {
|
||||
return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div class="avatars">
|
||||
<div class="avatars-item" v-for="user in slicedUsers">
|
||||
<UserAvatar :user="user" class="avatar-small" />
|
||||
</div>
|
||||
<router-link :to="userProfileLink(user)" class="avatars-item" v-for="user in slicedUsers">
|
||||
<UserAvatar :user="user" class="avatar-small" />
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
@goto="setHighlight"
|
||||
@toggleExpanded="toggleExpanded"
|
||||
:key="status.id"
|
||||
:inlineExpanded="collapsable"
|
||||
:inlineExpanded="collapsable && isExpanded"
|
||||
:statusoid="status"
|
||||
:expandable='!isExpanded'
|
||||
:focused="focused(status.id)"
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
@import '../../_variables.scss';
|
||||
|
||||
.media-modal-view {
|
||||
z-index: 1001;
|
||||
|
||||
&:hover {
|
||||
.modal-view-button-arrow {
|
||||
opacity: 0.75;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import PostStatusForm from '../post_status_form/post_status_form.vue'
|
||||
import { throttle } from 'lodash'
|
||||
import { debounce } from 'lodash'
|
||||
|
||||
const MobilePostStatusModal = {
|
||||
components: {
|
||||
|
@ -16,11 +16,15 @@ const MobilePostStatusModal = {
|
|||
}
|
||||
},
|
||||
created () {
|
||||
window.addEventListener('scroll', this.handleScroll)
|
||||
if (this.autohideFloatingPostButton) {
|
||||
this.activateFloatingPostButtonAutohide()
|
||||
}
|
||||
window.addEventListener('resize', this.handleOSK)
|
||||
},
|
||||
destroyed () {
|
||||
window.removeEventListener('scroll', this.handleScroll)
|
||||
if (this.autohideFloatingPostButton) {
|
||||
this.deactivateFloatingPostButtonAutohide()
|
||||
}
|
||||
window.removeEventListener('resize', this.handleOSK)
|
||||
},
|
||||
computed: {
|
||||
|
@ -28,10 +32,30 @@ const MobilePostStatusModal = {
|
|||
return this.$store.state.users.currentUser
|
||||
},
|
||||
isHidden () {
|
||||
return this.hidden || this.inputActive
|
||||
return this.autohideFloatingPostButton && (this.hidden || this.inputActive)
|
||||
},
|
||||
autohideFloatingPostButton () {
|
||||
return !!this.$store.state.config.autohideFloatingPostButton
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
autohideFloatingPostButton: function (isEnabled) {
|
||||
if (isEnabled) {
|
||||
this.activateFloatingPostButtonAutohide()
|
||||
} else {
|
||||
this.deactivateFloatingPostButtonAutohide()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
activateFloatingPostButtonAutohide () {
|
||||
window.addEventListener('scroll', this.handleScrollStart)
|
||||
window.addEventListener('scroll', this.handleScrollEnd)
|
||||
},
|
||||
deactivateFloatingPostButtonAutohide () {
|
||||
window.removeEventListener('scroll', this.handleScrollStart)
|
||||
window.removeEventListener('scroll', this.handleScrollEnd)
|
||||
},
|
||||
openPostForm () {
|
||||
this.postFormOpen = true
|
||||
this.hidden = true
|
||||
|
@ -65,26 +89,19 @@ const MobilePostStatusModal = {
|
|||
this.inputActive = false
|
||||
}
|
||||
},
|
||||
handleScroll: throttle(function () {
|
||||
const scrollAmount = window.scrollY - this.oldScrollPos
|
||||
const scrollingDown = scrollAmount > 0
|
||||
|
||||
if (scrollingDown !== this.scrollingDown) {
|
||||
this.amountScrolled = 0
|
||||
this.scrollingDown = scrollingDown
|
||||
if (!scrollingDown) {
|
||||
this.hidden = false
|
||||
}
|
||||
} else if (scrollingDown) {
|
||||
this.amountScrolled += scrollAmount
|
||||
if (this.amountScrolled > 100 && !this.hidden) {
|
||||
this.hidden = true
|
||||
}
|
||||
handleScrollStart: debounce(function () {
|
||||
if (window.scrollY > this.oldScrollPos) {
|
||||
this.hidden = true
|
||||
} else {
|
||||
this.hidden = false
|
||||
}
|
||||
|
||||
this.oldScrollPos = window.scrollY
|
||||
this.scrollingDown = scrollingDown
|
||||
}, 100)
|
||||
}, 100, {leading: true, trailing: false}),
|
||||
|
||||
handleScrollEnd: debounce(function () {
|
||||
this.hidden = false
|
||||
this.oldScrollPos = window.scrollY
|
||||
}, 100, {leading: false, trailing: true})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
>
|
||||
<div class="post-form-modal-panel panel" @click.stop="">
|
||||
<div class="panel-heading">{{$t('post_status.new_status')}}</div>
|
||||
<PostStatusForm class="panel-body" @posted="closePostForm"/>
|
||||
<PostStatusForm class="panel-body" @posted="closePostForm" />
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
|
|
|
@ -182,6 +182,9 @@ const PostStatusForm = {
|
|||
},
|
||||
safeDMEnabled () {
|
||||
return this.$store.state.instance.safeDM
|
||||
},
|
||||
hideScopeNotice () {
|
||||
return this.$store.state.config.hideScopeNotice
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -336,6 +339,9 @@ const PostStatusForm = {
|
|||
},
|
||||
changeVis (visibility) {
|
||||
this.newStatus.visibility = visibility
|
||||
},
|
||||
dismissScopeNotice () {
|
||||
this.$store.dispatch('setOption', { name: 'hideScopeNotice', value: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,25 @@
|
|||
class="visibility-notice">
|
||||
<router-link :to="{ name: 'user-settings' }">{{ $t('post_status.account_not_locked_warning_link') }}</router-link>
|
||||
</i18n>
|
||||
<p v-if="newStatus.visibility === 'direct'" class="visibility-notice">
|
||||
<p v-if="!hideScopeNotice && newStatus.visibility === 'public'" class="visibility-notice notice-dismissible">
|
||||
<span>{{ $t('post_status.scope_notice.public') }}</span>
|
||||
<a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
|
||||
<i class='icon-cancel'></i>
|
||||
</a>
|
||||
</p>
|
||||
<p v-else-if="!hideScopeNotice && newStatus.visibility === 'unlisted'" class="visibility-notice notice-dismissible">
|
||||
<span>{{ $t('post_status.scope_notice.unlisted') }}</span>
|
||||
<a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
|
||||
<i class='icon-cancel'></i>
|
||||
</a>
|
||||
</p>
|
||||
<p v-else-if="!hideScopeNotice && newStatus.visibility === 'private' && $store.state.users.currentUser.locked" class="visibility-notice notice-dismissible">
|
||||
<span>{{ $t('post_status.scope_notice.private') }}</span>
|
||||
<a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
|
||||
<i class='icon-cancel'></i>
|
||||
</a>
|
||||
</p>
|
||||
<p v-else-if="newStatus.visibility === 'direct'" class="visibility-notice">
|
||||
<span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
|
||||
<span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
|
||||
</p>
|
||||
|
|
|
@ -46,6 +46,7 @@ const settings = {
|
|||
streamingLocal: user.streaming,
|
||||
pauseOnUnfocusedLocal: user.pauseOnUnfocused,
|
||||
hoverPreviewLocal: user.hoverPreview,
|
||||
autohideFloatingPostButtonLocal: user.autohideFloatingPostButton,
|
||||
|
||||
hideMutedPostsLocal: typeof user.hideMutedPosts === 'undefined'
|
||||
? instance.hideMutedPosts
|
||||
|
@ -183,6 +184,9 @@ const settings = {
|
|||
hoverPreviewLocal (value) {
|
||||
this.$store.dispatch('setOption', { name: 'hoverPreview', value })
|
||||
},
|
||||
autohideFloatingPostButtonLocal (value) {
|
||||
this.$store.dispatch('setOption', { name: 'autohideFloatingPostButton', value })
|
||||
},
|
||||
muteWordsString (value) {
|
||||
value = filter(value.split('\n'), (word) => trim(word).length > 0)
|
||||
this.$store.dispatch('setOption', { name: 'muteWords', value })
|
||||
|
|
|
@ -122,6 +122,10 @@
|
|||
{{$t('settings.minimal_scopes_mode')}} {{$t('settings.instance_default', { value: minimalScopesModeDefault })}}
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" id="autohideFloatingPostButton" v-model="autohideFloatingPostButtonLocal">
|
||||
<label for="autohideFloatingPostButton">{{$t('settings.autohide_floating_post_button')}}</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ const Status = {
|
|||
data () {
|
||||
return {
|
||||
replying: false,
|
||||
expanded: false,
|
||||
unmuted: false,
|
||||
userExpanded: false,
|
||||
preview: null,
|
||||
|
@ -161,7 +160,7 @@ const Status = {
|
|||
if (this.$store.state.config.replyVisibility === 'all') {
|
||||
return false
|
||||
}
|
||||
if (this.inlineExpanded || this.expanded || this.inConversation || !this.isReply) {
|
||||
if (this.inConversation || !this.isReply) {
|
||||
return false
|
||||
}
|
||||
if (this.status.user.id === this.$store.state.users.currentUser.id) {
|
||||
|
@ -175,7 +174,7 @@ const Status = {
|
|||
if (this.status.user.id === this.status.attentions[i].id) {
|
||||
continue
|
||||
}
|
||||
if (checkFollowing && this.status.attentions[i].following) {
|
||||
if (checkFollowing && this.$store.getters.findUser(this.status.attentions[i].id).following) {
|
||||
return false
|
||||
}
|
||||
if (this.status.attentions[i].id === this.$store.state.users.currentUser.id) {
|
||||
|
|
|
@ -139,7 +139,7 @@
|
|||
</div>
|
||||
|
||||
<transition name="fade">
|
||||
<div class="favs-repeated-users" v-if="combinedFavsAndRepeatsUsers.length > 0 && isFocused">
|
||||
<div class="favs-repeated-users" v-if="isFocused && combinedFavsAndRepeatsUsers.length > 0">
|
||||
<div class="stats">
|
||||
<div class="stat-count" v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0">
|
||||
<a class="stat-title">{{ $t('status.repeats') }}</a>
|
||||
|
|
|
@ -94,6 +94,11 @@
|
|||
"direct_warning_to_all": "This post will be visible to all the mentioned users.",
|
||||
"direct_warning_to_first_only": "This post will only be visible to the mentioned users at the beginning of the message.",
|
||||
"posting": "Posting",
|
||||
"scope_notice": {
|
||||
"public": "This post will be visible to everyone",
|
||||
"private": "This post will be visible to your followers only",
|
||||
"unlisted": "This post will not be visible in Public Timeline and The Whole Known Network"
|
||||
},
|
||||
"scope": {
|
||||
"direct": "Direct - Post to mentioned users only",
|
||||
"private": "Followers-only - Post to followers only",
|
||||
|
@ -233,6 +238,7 @@
|
|||
"reply_visibility_all": "Show all replies",
|
||||
"reply_visibility_following": "Only show replies directed at me or users I'm following",
|
||||
"reply_visibility_self": "Only show replies directed at me",
|
||||
"autohide_floating_post_button": "Automatically hide New Post button (mobile)",
|
||||
"saving_err": "Error saving settings",
|
||||
"saving_ok": "Settings saved",
|
||||
"search_user_to_block": "Search whom you want to block",
|
||||
|
|
|
@ -420,6 +420,7 @@
|
|||
"muted": "Silenciado",
|
||||
"per_day": "por día",
|
||||
"remote_follow": "Seguir",
|
||||
"report": "Reportar",
|
||||
"statuses": "Estados",
|
||||
"unblock": "Desbloquear",
|
||||
"unblock_progress": "Desbloqueando...",
|
||||
|
@ -451,6 +452,15 @@
|
|||
"timeline_title": "Linea temporal del usuario",
|
||||
"profile_does_not_exist": "Lo sentimos, este perfil no existe.",
|
||||
"profile_loading_error": "Lo sentimos, hubo un error al cargar este perfil."
|
||||
},
|
||||
"user_reporting": {
|
||||
"title": "Reportando a {0}",
|
||||
"add_comment_description": "El informe será enviado a los moderadores de su instancia. Puedes proporcionar una explicación de por qué estás reportando esta cuenta a continuación:",
|
||||
"additional_comments": "Comentarios adicionales",
|
||||
"forward_description": "La cuenta es de otro servidor. ¿Enviar una copia del informe allí también?",
|
||||
"forward_to": "Reenviar a {0}",
|
||||
"submit": "Enviar",
|
||||
"generic_error": "Se produjo un error al procesar la solicitud."
|
||||
},
|
||||
"who_to_follow": {
|
||||
"more": "Más",
|
||||
|
@ -477,4 +487,4 @@
|
|||
"TiB": "TiB"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,8 +42,13 @@
|
|||
"attachments_sensitive": "Вложения содержат чувствительный контент",
|
||||
"content_warning": "Тема (не обязательно)",
|
||||
"default": "Что нового?",
|
||||
"direct_warning": "Этот пост будет видет только упомянутым пользователям",
|
||||
"direct_warning": "Этот пост будет виден только упомянутым пользователям",
|
||||
"posting": "Отправляется",
|
||||
"scope_notice": {
|
||||
"public": "Этот пост будет виден всем",
|
||||
"private": "Этот пост будет виден только вашим подписчикам",
|
||||
"unlisted": "Этот пост не будет виден в публичной и федеративной ленте"
|
||||
},
|
||||
"scope": {
|
||||
"direct": "Личное - этот пост видят только те кто в нём упомянут",
|
||||
"private": "Для подписчиков - этот пост видят только подписчики",
|
||||
|
@ -152,6 +157,7 @@
|
|||
"reply_visibility_all": "Показывать все ответы",
|
||||
"reply_visibility_following": "Показывать только ответы мне и тех на кого я подписан",
|
||||
"reply_visibility_self": "Показывать только ответы мне",
|
||||
"autohide_floating_post_button": "Автоматически скрывать кнопку постинга (в мобильной версии)",
|
||||
"saving_err": "Не удалось сохранить настройки",
|
||||
"saving_ok": "Сохранено",
|
||||
"security_tab": "Безопасность",
|
||||
|
|
|
@ -17,6 +17,7 @@ const defaultState = {
|
|||
autoLoad: true,
|
||||
streaming: false,
|
||||
hoverPreview: true,
|
||||
autohideFloatingPostButton: false,
|
||||
pauseOnUnfocused: true,
|
||||
stopGifs: false,
|
||||
replyVisibility: 'all',
|
||||
|
@ -30,6 +31,7 @@ const defaultState = {
|
|||
muteWords: [],
|
||||
highlight: {},
|
||||
interfaceLanguage: browserLocale,
|
||||
hideScopeNotice: false,
|
||||
scopeCopy: undefined, // instance default
|
||||
subjectLineBehavior: undefined, // instance default
|
||||
alwaysShowSubjectInput: undefined, // instance default
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { remove, slice, each, find, maxBy, minBy, merge, first, last, isArray, omitBy } from 'lodash'
|
||||
import { remove, slice, each, findIndex, find, maxBy, minBy, merge, first, last, isArray, omitBy } from 'lodash'
|
||||
import { set } from 'vue'
|
||||
import apiService from '../services/api/api.service.js'
|
||||
// import parse from '../services/status_parser/status_parser.js'
|
||||
|
@ -402,12 +402,27 @@ export const mutations = {
|
|||
},
|
||||
setFavorited (state, { status, value }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
|
||||
if (newStatus.favorited !== value) {
|
||||
if (value) {
|
||||
newStatus.fave_num++
|
||||
} else {
|
||||
newStatus.fave_num--
|
||||
}
|
||||
}
|
||||
|
||||
newStatus.favorited = value
|
||||
},
|
||||
setFavoritedConfirm (state, { status }) {
|
||||
setFavoritedConfirm (state, { status, user }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
newStatus.favorited = status.favorited
|
||||
newStatus.fave_num = status.fave_num
|
||||
const index = findIndex(newStatus.favoritedBy, { id: user.id })
|
||||
if (index !== -1 && !newStatus.favorited) {
|
||||
newStatus.favoritedBy.splice(index, 1)
|
||||
} else if (index === -1 && newStatus.favorited) {
|
||||
newStatus.favoritedBy.push(user)
|
||||
}
|
||||
},
|
||||
setRetweeted (state, { status, value }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
|
@ -422,6 +437,17 @@ export const mutations = {
|
|||
|
||||
newStatus.repeated = value
|
||||
},
|
||||
setRetweetedConfirm (state, { status, user }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
newStatus.repeated = status.repeated
|
||||
newStatus.repeat_num = status.repeat_num
|
||||
const index = findIndex(newStatus.rebloggedBy, { id: user.id })
|
||||
if (index !== -1 && !newStatus.repeated) {
|
||||
newStatus.rebloggedBy.splice(index, 1)
|
||||
} else if (index === -1 && newStatus.repeated) {
|
||||
newStatus.rebloggedBy.push(user)
|
||||
}
|
||||
},
|
||||
setDeleted (state, { status }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
newStatus.deleted = true
|
||||
|
@ -461,11 +487,9 @@ export const mutations = {
|
|||
state.timelines[timeline].flushMarker = id
|
||||
},
|
||||
addFavsAndRepeats (state, { id, favoritedByUsers, rebloggedByUsers }) {
|
||||
state.allStatusesObject[id] = {
|
||||
...state.allStatusesObject[id],
|
||||
favoritedBy: favoritedByUsers,
|
||||
rebloggedBy: rebloggedByUsers
|
||||
}
|
||||
const newStatus = state.allStatusesObject[id]
|
||||
newStatus.favoritedBy = favoritedByUsers.filter(_ => _)
|
||||
newStatus.rebloggedBy = rebloggedByUsers.filter(_ => _)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,27 +524,26 @@ const statuses = {
|
|||
favorite ({ rootState, commit }, status) {
|
||||
// Optimistic favoriting...
|
||||
commit('setFavorited', { status, value: true })
|
||||
apiService.favorite({ id: status.id, credentials: rootState.users.currentUser.credentials })
|
||||
.then(status => {
|
||||
commit('setFavoritedConfirm', { status })
|
||||
})
|
||||
rootState.api.backendInteractor.favorite(status.id)
|
||||
.then(status => commit('setFavoritedConfirm', { status, user: rootState.users.currentUser }))
|
||||
},
|
||||
unfavorite ({ rootState, commit }, status) {
|
||||
// Optimistic favoriting...
|
||||
// Optimistic unfavoriting...
|
||||
commit('setFavorited', { status, value: false })
|
||||
apiService.unfavorite({ id: status.id, credentials: rootState.users.currentUser.credentials })
|
||||
.then(status => {
|
||||
commit('setFavoritedConfirm', { status })
|
||||
})
|
||||
rootState.api.backendInteractor.unfavorite(status.id)
|
||||
.then(status => commit('setFavoritedConfirm', { status, user: rootState.users.currentUser }))
|
||||
},
|
||||
retweet ({ rootState, commit }, status) {
|
||||
// Optimistic retweeting...
|
||||
commit('setRetweeted', { status, value: true })
|
||||
apiService.retweet({ id: status.id, credentials: rootState.users.currentUser.credentials })
|
||||
rootState.api.backendInteractor.retweet(status.id)
|
||||
.then(status => commit('setRetweetedConfirm', { status: status.retweeted_status, user: rootState.users.currentUser }))
|
||||
},
|
||||
unretweet ({ rootState, commit }, status) {
|
||||
// Optimistic unretweeting...
|
||||
commit('setRetweeted', { status, value: false })
|
||||
apiService.unretweet({ id: status.id, credentials: rootState.users.currentUser.credentials })
|
||||
rootState.api.backendInteractor.unretweet(status.id)
|
||||
.then(status => commit('setRetweetedConfirm', { status, user: rootState.users.currentUser }))
|
||||
},
|
||||
queueFlush ({ rootState, commit }, { timeline, id }) {
|
||||
commit('queueFlush', { timeline, id })
|
||||
|
@ -537,14 +560,7 @@ const statuses = {
|
|||
rootState.api.backendInteractor.fetchFavoritedByUsers(id),
|
||||
rootState.api.backendInteractor.fetchRebloggedByUsers(id)
|
||||
]).then(([favoritedByUsers, rebloggedByUsers]) =>
|
||||
commit(
|
||||
'addFavsAndRepeats',
|
||||
{
|
||||
id,
|
||||
favoritedByUsers: favoritedByUsers.filter(_ => _),
|
||||
rebloggedByUsers: rebloggedByUsers.filter(_ => _)
|
||||
}
|
||||
)
|
||||
commit('addFavsAndRepeats', { id, favoritedByUsers, rebloggedByUsers })
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -506,62 +506,22 @@ const verifyCredentials = (user) => {
|
|||
}
|
||||
|
||||
const favorite = ({ id, credentials }) => {
|
||||
return fetch(MASTODON_FAVORITE_URL(id), {
|
||||
headers: authHeaders(credentials),
|
||||
method: 'POST'
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
} else {
|
||||
throw new Error('Error favoriting post')
|
||||
}
|
||||
})
|
||||
return promisedRequest({ url: MASTODON_FAVORITE_URL(id), method: 'POST', credentials })
|
||||
.then((data) => parseStatus(data))
|
||||
}
|
||||
|
||||
const unfavorite = ({ id, credentials }) => {
|
||||
return fetch(MASTODON_UNFAVORITE_URL(id), {
|
||||
headers: authHeaders(credentials),
|
||||
method: 'POST'
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
} else {
|
||||
throw new Error('Error removing favorite')
|
||||
}
|
||||
})
|
||||
return promisedRequest({ url: MASTODON_UNFAVORITE_URL(id), method: 'POST', credentials })
|
||||
.then((data) => parseStatus(data))
|
||||
}
|
||||
|
||||
const retweet = ({ id, credentials }) => {
|
||||
return fetch(MASTODON_RETWEET_URL(id), {
|
||||
headers: authHeaders(credentials),
|
||||
method: 'POST'
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
} else {
|
||||
throw new Error('Error repeating post')
|
||||
}
|
||||
})
|
||||
return promisedRequest({ url: MASTODON_RETWEET_URL(id), method: 'POST', credentials })
|
||||
.then((data) => parseStatus(data))
|
||||
}
|
||||
|
||||
const unretweet = ({ id, credentials }) => {
|
||||
return fetch(MASTODON_UNRETWEET_URL(id), {
|
||||
headers: authHeaders(credentials),
|
||||
method: 'POST'
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
} else {
|
||||
throw new Error('Error removing repeat')
|
||||
}
|
||||
})
|
||||
return promisedRequest({ url: MASTODON_UNRETWEET_URL(id), method: 'POST', credentials })
|
||||
.then((data) => parseStatus(data))
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,11 @@ const backendInteractorService = (credentials) => {
|
|||
const fetchRebloggedByUsers = (id) => apiService.fetchRebloggedByUsers({id})
|
||||
const reportUser = (params) => apiService.reportUser({credentials, ...params})
|
||||
|
||||
const favorite = (id) => apiService.favorite({id, credentials})
|
||||
const unfavorite = (id) => apiService.unfavorite({id, credentials})
|
||||
const retweet = (id) => apiService.retweet({id, credentials})
|
||||
const unretweet = (id) => apiService.unretweet({id, credentials})
|
||||
|
||||
const backendInteractorServiceInstance = {
|
||||
fetchStatus,
|
||||
fetchConversation,
|
||||
|
@ -161,7 +166,11 @@ const backendInteractorService = (credentials) => {
|
|||
denyUser,
|
||||
fetchFavoritedByUsers,
|
||||
fetchRebloggedByUsers,
|
||||
reportUser
|
||||
reportUser,
|
||||
favorite,
|
||||
unfavorite,
|
||||
retweet,
|
||||
unretweet
|
||||
}
|
||||
|
||||
return backendInteractorServiceInstance
|
||||
|
|
|
@ -309,7 +309,7 @@ export const parseNotification = (data) => {
|
|||
}
|
||||
|
||||
output.created_at = new Date(data.created_at)
|
||||
output.id = data.id
|
||||
output.id = parseInt(data.id)
|
||||
|
||||
return output
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue