moderately usable state
This commit is contained in:
parent
d77163cf91
commit
d0c3eafa84
15 changed files with 570 additions and 338 deletions
|
|
@ -110,8 +110,6 @@ const conversation = {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
status() {
|
status() {
|
||||||
console.log(this.statusId)
|
|
||||||
console.log(useStatusesStore().allStatuses.get(this.statusId))
|
|
||||||
return useStatusesStore().allStatuses.get(this.statusId)
|
return useStatusesStore().allStatuses.get(this.statusId)
|
||||||
},
|
},
|
||||||
maxDepthToShowByDefault() {
|
maxDepthToShowByDefault() {
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ import {
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
|
import { useScrobblesStore } from 'src/stores/scrobbles.js'
|
||||||
import { useStatusesStore } from 'src/stores/statuses.js'
|
import { useStatusesStore } from 'src/stores/statuses.js'
|
||||||
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
import { useSyncConfigStore } from 'src/stores/sync_config.js'
|
||||||
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
|
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
|
||||||
import { useUsersStore } from 'src/stores/users.js'
|
import { useUsersStore } from 'src/stores/users.js'
|
||||||
import { useScrobblesStore } from 'src/stores/scrobbles.js'
|
|
||||||
|
|
||||||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||||
|
|
||||||
|
|
@ -136,6 +136,12 @@ const Status = {
|
||||||
status() {
|
status() {
|
||||||
return this.statusoid ?? useStatusesStore().allStatuses.get(this.statusId)
|
return this.statusoid ?? useStatusesStore().allStatuses.get(this.statusId)
|
||||||
},
|
},
|
||||||
|
repeater() {
|
||||||
|
return useUsersStore().findUser(this.status.user.id)
|
||||||
|
},
|
||||||
|
user() {
|
||||||
|
return useUsersStore().findUser(this.mainStatus.user.id)
|
||||||
|
},
|
||||||
showReasonMutedThread() {
|
showReasonMutedThread() {
|
||||||
return (
|
return (
|
||||||
(this.mainStatus.thread_muted ||
|
(this.mainStatus.thread_muted ||
|
||||||
|
|
@ -153,38 +159,31 @@ const Status = {
|
||||||
return this.mergedConfig.scaleMfm
|
return this.mergedConfig.scaleMfm
|
||||||
},
|
},
|
||||||
repeaterClass() {
|
repeaterClass() {
|
||||||
const user = this.status.user
|
return highlightClass(this.repeater)
|
||||||
return highlightClass(user)
|
|
||||||
},
|
},
|
||||||
userClass() {
|
userClass() {
|
||||||
const user = this.retweet
|
return highlightClass(this.user)
|
||||||
? this.status.retweeted_status.user
|
|
||||||
: this.status.user
|
|
||||||
return highlightClass(user)
|
|
||||||
},
|
},
|
||||||
deleted() {
|
deleted() {
|
||||||
return this.status.deleted
|
return this.status.deleted
|
||||||
},
|
},
|
||||||
repeaterStyle() {
|
repeaterStyle() {
|
||||||
const user = this.status.user
|
const user = this.status.user
|
||||||
return highlightStyle(useUserHighlightStore().get(user.screen_name))
|
return highlightStyle(useUserHighlightStore().get(this.repeater.screen_name))
|
||||||
},
|
},
|
||||||
userStyle() {
|
userStyle() {
|
||||||
if (this.noHeading) return
|
if (this.noHeading) return
|
||||||
const user = this.retweet
|
return highlightStyle(useUserHighlightStore().get(this.user.screen_name))
|
||||||
? this.status.retweeted_status.user
|
|
||||||
: this.status.user
|
|
||||||
return highlightStyle(useUserHighlightStore().get(user.screen_name))
|
|
||||||
},
|
},
|
||||||
userProfileLink() {
|
userProfileLink() {
|
||||||
return this.generateUserProfileLink(
|
return this.generateUserProfileLink(
|
||||||
this.status.user.id,
|
this.user.id,
|
||||||
this.status.user.screen_name,
|
this.user.screen_name,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
replyProfileLink() {
|
replyProfileLink() {
|
||||||
if (this.isReply) {
|
if (this.isReply) {
|
||||||
const user = useUsersStore().findUser(this.status.in_reply_to_user_id)
|
const user = useUsersStore().findUser(this.mainStatus.in_reply_to_user_id)
|
||||||
// FIXME Why user not found sometimes???
|
// FIXME Why user not found sometimes???
|
||||||
return user ? user.statusnet_profile_url : 'NOT_FOUND'
|
return user ? user.statusnet_profile_url : 'NOT_FOUND'
|
||||||
}
|
}
|
||||||
|
|
@ -192,19 +191,16 @@ const Status = {
|
||||||
retweet() {
|
retweet() {
|
||||||
return !!this.status.retweeted_status
|
return !!this.status.retweeted_status
|
||||||
},
|
},
|
||||||
retweeterUser() {
|
repeaterName() {
|
||||||
return this.status.user
|
|
||||||
},
|
|
||||||
retweeter() {
|
|
||||||
return this.status.user.name || this.status.user.screen_name_ui
|
return this.status.user.name || this.status.user.screen_name_ui
|
||||||
},
|
},
|
||||||
retweeterHtml() {
|
repeaterHtml() {
|
||||||
return this.status.user.name
|
return this.status.user.name
|
||||||
},
|
},
|
||||||
retweeterProfileLink() {
|
repeaterProfileLink() {
|
||||||
return this.generateUserProfileLink(
|
return this.generateUserProfileLink(
|
||||||
this.status.user.id,
|
this.repeater.id,
|
||||||
this.status.user.screen_name,
|
this.repeater.screen_name,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
mainStatus() {
|
mainStatus() {
|
||||||
|
|
@ -214,10 +210,6 @@ const Status = {
|
||||||
return this.status
|
return this.status
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
statusFromGlobalRepository() {
|
|
||||||
// NOTE: Consider to replace status with statusFromGlobalRepository
|
|
||||||
return useStatusesStore().allStatuses.get(this.status.id)
|
|
||||||
},
|
|
||||||
loggedIn() {
|
loggedIn() {
|
||||||
return !!this.currentUser
|
return !!this.currentUser
|
||||||
},
|
},
|
||||||
|
|
@ -367,22 +359,22 @@ const Status = {
|
||||||
},
|
},
|
||||||
isReply() {
|
isReply() {
|
||||||
return !!(
|
return !!(
|
||||||
this.status.in_reply_to_status_id && this.status.in_reply_to_user_id
|
this.mainStatus.in_reply_to_status_id && this.mainStatus.in_reply_to_user_id
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
replyToName() {
|
replyToName() {
|
||||||
if (this.status.in_reply_to_screen_name) {
|
if (this.mainStatus.in_reply_to_screen_name) {
|
||||||
return this.status.in_reply_to_screen_name
|
return this.status.in_reply_to_screen_name
|
||||||
} else {
|
} else {
|
||||||
const user = useUsersStore().findUser(this.status.in_reply_to_user_id)
|
const user = useUsersStore().findUser(this.mainStatus.in_reply_to_user_id)
|
||||||
return user?.screen_name_ui
|
return user?.screen_name_ui
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
combinedFavsAndRepeatsUsers() {
|
combinedFavsAndRepeatsUsers() {
|
||||||
// Use the status from the global status repository since favs and repeats are saved in it
|
// Use the status from the global status repository since favs and repeats are saved in it
|
||||||
const combinedUsers = [].concat(
|
const combinedUsers = [].concat(
|
||||||
this.statusFromGlobalRepository.favoritedBy,
|
this.mainStatus.favoritedBy,
|
||||||
this.statusFromGlobalRepository.rebloggedBy,
|
this.mainStatus.rebloggedBy,
|
||||||
)
|
)
|
||||||
return uniqBy(combinedUsers, 'id')
|
return uniqBy(combinedUsers, 'id')
|
||||||
},
|
},
|
||||||
|
|
@ -400,7 +392,7 @@ const Status = {
|
||||||
!this.hidePostStats &&
|
!this.hidePostStats &&
|
||||||
this.focused &&
|
this.focused &&
|
||||||
(this.combinedFavsAndRepeatsUsers.length > 0 ||
|
(this.combinedFavsAndRepeatsUsers.length > 0 ||
|
||||||
this.statusFromGlobalRepository.quotes_count)
|
this.mainStatus.quotes_count)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
muteBotStatuses() {
|
muteBotStatuses() {
|
||||||
|
|
@ -431,7 +423,7 @@ const Status = {
|
||||||
return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility)
|
return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility)
|
||||||
},
|
},
|
||||||
isEdited() {
|
isEdited() {
|
||||||
return this.status.edited_at !== null
|
return this.mainStatus.edited_at !== null
|
||||||
},
|
},
|
||||||
editingAvailable() {
|
editingAvailable() {
|
||||||
return useInstanceCapabilitiesStore().editingAvailable
|
return useInstanceCapabilitiesStore().editingAvailable
|
||||||
|
|
@ -562,22 +554,22 @@ const Status = {
|
||||||
focused: function (id) {
|
focused: function (id) {
|
||||||
this.scrollIfFocused(id)
|
this.scrollIfFocused(id)
|
||||||
},
|
},
|
||||||
'status.repeat_num': function (num) {
|
'mainStatus.repeat_num': function (num) {
|
||||||
// refetch repeats when repeat_num is changed in any way
|
// refetch repeats when repeat_num is changed in any way
|
||||||
if (
|
if (
|
||||||
this.focused &&
|
this.focused &&
|
||||||
this.statusFromGlobalRepository.rebloggedBy &&
|
this.mainStatus.rebloggedBy &&
|
||||||
this.statusFromGlobalRepository.rebloggedBy.length !== num
|
this.mainStatus.rebloggedBy.length !== num
|
||||||
) {
|
) {
|
||||||
this.$store.dispatch('fetchRepeats', this.status.id)
|
this.$store.dispatch('fetchRepeats', this.status.id)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'status.fave_num': function (num) {
|
'mainStatus.fave_num': function (num) {
|
||||||
// refetch favs when fave_num is changed in any way
|
// refetch favs when fave_num is changed in any way
|
||||||
if (
|
if (
|
||||||
this.focused &&
|
this.focused &&
|
||||||
this.statusFromGlobalRepository.favoritedBy &&
|
this.mainStatus.favoritedBy &&
|
||||||
this.statusFromGlobalRepository.favoritedBy.length !== num
|
this.mainStatus.favoritedBy.length !== num
|
||||||
) {
|
) {
|
||||||
this.$store.dispatch('fetchFavs', this.status.id)
|
this.$store.dispatch('fetchFavs', this.status.id)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
icon="retweet"
|
icon="retweet"
|
||||||
/>
|
/>
|
||||||
<user-link
|
<user-link
|
||||||
:user="status.user"
|
:user="repeater"
|
||||||
:at="false"
|
:at="false"
|
||||||
/>
|
/>
|
||||||
</small>
|
</small>
|
||||||
|
|
@ -53,32 +53,31 @@
|
||||||
class="status-container repeat-info"
|
class="status-container repeat-info"
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
v-if="retweet"
|
|
||||||
class="left-side repeater-avatar"
|
class="left-side repeater-avatar"
|
||||||
:user-id="statusoid.user.id"
|
:user-id="repeater.id"
|
||||||
/>
|
/>
|
||||||
<div class="right-side faint">
|
<div class="right-side faint">
|
||||||
<bdi
|
<bdi
|
||||||
class="status-username repeater-name"
|
class="status-username repeater-name"
|
||||||
:title="retweeter"
|
:title="repeaterName"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="retweeterHtml"
|
v-if="repeaterHtml"
|
||||||
:to="retweeterProfileLink"
|
:to="repeaterProfileLink"
|
||||||
>
|
>
|
||||||
<RichContent
|
<RichContent
|
||||||
:html="retweeterHtml"
|
:html="repeaterHtml"
|
||||||
:emoji="retweeterUser.emoji"
|
:emoji="repeater.emoji"
|
||||||
:allow-non-square-emoji="allowNonSquareEmoji"
|
:allow-non-square-emoji="allowNonSquareEmoji"
|
||||||
:pause-mfm="pauseMfm"
|
:pause-mfm="pauseMfm"
|
||||||
:scale-mfm="scaleMfm"
|
:scale-mfm="scaleMfm"
|
||||||
:is-local="retweeterUser.is_local"
|
:is-local="repeater.is_local"
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
v-else
|
v-else
|
||||||
:to="retweeterProfileLink"
|
:to="repeaterProfileLink"
|
||||||
>{{ retweeter }}</router-link>
|
>{{ repeaterName }}</router-link>
|
||||||
</bdi>
|
</bdi>
|
||||||
<div class="repeat-label">
|
<div class="repeat-label">
|
||||||
<FAIcon
|
<FAIcon
|
||||||
|
|
@ -103,24 +102,24 @@
|
||||||
class="left-side"
|
class="left-side"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
v-if="status.user?.name"
|
v-if="user.name"
|
||||||
:href="$router.resolve(userProfileLink).href"
|
:href="$router.resolve(userProfileLink).href"
|
||||||
@click.prevent
|
@click.prevent
|
||||||
>
|
>
|
||||||
<UserPopover
|
<UserPopover
|
||||||
:user-id="status.user.id"
|
:user-id="user.id"
|
||||||
:overlay-centers="true"
|
:overlay-centers="true"
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
class="post-avatar"
|
class="post-avatar"
|
||||||
:compact="compact"
|
:compact="compact"
|
||||||
:user-id="status?.user.id"
|
:user-id="user.id"
|
||||||
/>
|
/>
|
||||||
</UserPopover>
|
</UserPopover>
|
||||||
</a>
|
</a>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
v-else
|
v-else
|
||||||
:user-id="status?.user.id"
|
:user-id="user.id"
|
||||||
class="post-avatar"
|
class="post-avatar"
|
||||||
:compact="compact"
|
:compact="compact"
|
||||||
:title="$t('status.unknown_user_info')"
|
:title="$t('status.unknown_user_info')"
|
||||||
|
|
@ -133,38 +132,38 @@
|
||||||
>
|
>
|
||||||
<div class="heading-name-row">
|
<div class="heading-name-row">
|
||||||
<div
|
<div
|
||||||
v-if="status.user"
|
v-if="user"
|
||||||
class="heading-left"
|
class="heading-left"
|
||||||
>
|
>
|
||||||
<h4
|
<h4
|
||||||
v-if="status.user.name_html"
|
v-if="user.name_html"
|
||||||
class="status-username"
|
class="status-username"
|
||||||
:title="status.user.name"
|
:title="user.name"
|
||||||
>
|
>
|
||||||
<RichContent
|
<RichContent
|
||||||
:html="status.user.name"
|
:html="user.name"
|
||||||
:emoji="status.user.emoji"
|
:emoji="user.emoji"
|
||||||
:allow-non-square-emoji="allowNonSquareEmoji"
|
:allow-non-square-emoji="allowNonSquareEmoji"
|
||||||
:is-local="status.user.is_local"
|
:is-local="user.is_local"
|
||||||
/>
|
/>
|
||||||
</h4>
|
</h4>
|
||||||
<h4
|
<h4
|
||||||
v-else
|
v-else
|
||||||
class="status-username"
|
class="status-username"
|
||||||
:title="status.user.name"
|
:title="user.name"
|
||||||
>
|
>
|
||||||
{{ status.user.name }}
|
{{ user.name }}
|
||||||
</h4>
|
</h4>
|
||||||
<user-link
|
<user-link
|
||||||
class="account-name"
|
class="account-name"
|
||||||
:title="status.user.screen_name_ui"
|
:title="user.screen_name_ui"
|
||||||
:user="status.user"
|
:user="user"
|
||||||
:at="false"
|
:at="false"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="!!(status.user && status.user.favicon)"
|
v-if="!!(user && user.favicon)"
|
||||||
class="status-favicon"
|
class="status-favicon"
|
||||||
:src="status.user.favicon"
|
:src="user.favicon"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -184,12 +183,12 @@
|
||||||
:to="{ name: 'conversation', params: { id: status.id } }"
|
:to="{ name: 'conversation', params: { id: status.id } }"
|
||||||
>
|
>
|
||||||
<Timeago
|
<Timeago
|
||||||
:time="status.created_at"
|
:time="mainStatus.created_at"
|
||||||
:auto-update="60"
|
:auto-update="60"
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<span
|
<span
|
||||||
v-if="status.visibility"
|
v-if="mainStatus.visibility"
|
||||||
class="visibility-icon"
|
class="visibility-icon"
|
||||||
:title="visibilityLocalized"
|
:title="visibilityLocalized"
|
||||||
>
|
>
|
||||||
|
|
@ -305,10 +304,10 @@
|
||||||
<template #replyToWithIcon>
|
<template #replyToWithIcon>
|
||||||
<StatusPopover
|
<StatusPopover
|
||||||
v-if="!isPreview"
|
v-if="!isPreview"
|
||||||
:status-id="status.parent_visible && status.in_reply_to_status_id"
|
:status-id="mainStatus.parent_visible && mainStatus.in_reply_to_status_id"
|
||||||
class="reply-to-popover"
|
class="reply-to-popover"
|
||||||
style="min-width: 0;"
|
style="min-width: 0;"
|
||||||
:class="{ '-strikethrough': !status.parent_visible }"
|
:class="{ '-strikethrough': !mainStatus.parent_visible }"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="button-unstyled reply-to"
|
class="button-unstyled reply-to"
|
||||||
|
|
@ -397,7 +396,7 @@
|
||||||
<template #time>
|
<template #time>
|
||||||
<Timeago
|
<Timeago
|
||||||
template-key="time.in_past"
|
template-key="time.in_past"
|
||||||
:time="status.edited_at"
|
:time="mainStatus.edited_at"
|
||||||
:auto-update="60"
|
:auto-update="60"
|
||||||
:long-format="true"
|
:long-format="true"
|
||||||
/>
|
/>
|
||||||
|
|
@ -462,31 +461,31 @@
|
||||||
>
|
>
|
||||||
<div class="stats">
|
<div class="stats">
|
||||||
<UserListPopover
|
<UserListPopover
|
||||||
v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0"
|
v-if="mainStatus.rebloggedBy && mainStatus.rebloggedBy.length > 0"
|
||||||
:users="statusFromGlobalRepository.rebloggedBy"
|
:users="mainStatus.rebloggedBy"
|
||||||
>
|
>
|
||||||
<div class="stat-count">
|
<div class="stat-count">
|
||||||
<a class="stat-title">{{ $t('status.repeats') }}</a>
|
<a class="stat-title">{{ $t('status.repeats') }}</a>
|
||||||
<div class="stat-number">
|
<div class="stat-number">
|
||||||
{{ statusFromGlobalRepository.rebloggedBy.length }}
|
{{ mainStatus.rebloggedBy.length }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</UserListPopover>
|
</UserListPopover>
|
||||||
<UserListPopover
|
<UserListPopover
|
||||||
v-if="statusFromGlobalRepository.favoritedBy && statusFromGlobalRepository.favoritedBy.length > 0"
|
v-if="mainStatus.favoritedBy && mainStatus.favoritedBy.length > 0"
|
||||||
:users="statusFromGlobalRepository.favoritedBy"
|
:users="mainStatus.favoritedBy"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="stat-count"
|
class="stat-count"
|
||||||
>
|
>
|
||||||
<a class="stat-title">{{ $t('status.favorites') }}</a>
|
<a class="stat-title">{{ $t('status.favorites') }}</a>
|
||||||
<div class="stat-number">
|
<div class="stat-number">
|
||||||
{{ statusFromGlobalRepository.favoritedBy.length }}
|
{{ mainStatus.favoritedBy.length }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</UserListPopover>
|
</UserListPopover>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="statusFromGlobalRepository.quotes_count > 0"
|
v-if="mainStatus.quotes_count > 0"
|
||||||
:to="{ name: 'quotes', params: { id: status.id } }"
|
:to="{ name: 'quotes', params: { id: status.id } }"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
@ -494,7 +493,7 @@
|
||||||
>
|
>
|
||||||
<a class="stat-title">{{ $t('status.quotes') }}</a>
|
<a class="stat-title">{{ $t('status.quotes') }}</a>
|
||||||
<div class="stat-number">
|
<div class="stat-number">
|
||||||
{{ statusFromGlobalRepository.quotes_count }}
|
{{ mainStatus.quotes_count }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
@ -507,13 +506,13 @@
|
||||||
|
|
||||||
<EmojiReactions
|
<EmojiReactions
|
||||||
v-if="(mergedConfig.emojiReactionsOnTimeline || focused) && (!noHeading && !isPreview)"
|
v-if="(mergedConfig.emojiReactionsOnTimeline || focused) && (!noHeading && !isPreview)"
|
||||||
:status="status"
|
:status="mainStatus"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatusActionButtons
|
<StatusActionButtons
|
||||||
v-if="!noHeading && !isPreview"
|
v-if="!noHeading && !isPreview"
|
||||||
class="status-action-buttons"
|
class="status-action-buttons"
|
||||||
:status="status"
|
:status="mainStatus"
|
||||||
:replying="replying"
|
:replying="replying"
|
||||||
@toggle-replying="toggleReplyForm"
|
@toggle-replying="toggleReplyForm"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,11 @@ const StatusPopover = {
|
||||||
error: false,
|
error: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
status() {
|
||||||
|
return useStatusesStore().allStatuses.get(this.statusId)
|
||||||
|
},
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
Popover,
|
Popover,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import ScrollTopButton from 'src/components/scroll_top_button/scroll_top_button.
|
||||||
import TimelineMenu from 'src/components/timeline_menu/timeline_menu.vue'
|
import TimelineMenu from 'src/components/timeline_menu/timeline_menu.vue'
|
||||||
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
import { useStatusesStore } from 'src/stores/statuses.js'
|
||||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
import { useTimelinesStore } from 'src/stores/timelines.js'
|
import { useTimelinesStore } from 'src/stores/timelines.js'
|
||||||
|
|
||||||
|
|
@ -54,8 +55,9 @@ const Timeline = {
|
||||||
return useTimelinesStore()[this.timelineRef.name]
|
return useTimelinesStore()[this.timelineRef.name]
|
||||||
},
|
},
|
||||||
filteredVisibleStatuses() {
|
filteredVisibleStatuses() {
|
||||||
return [...this.timeline.visibleStatusesIds.keys()]
|
return this.timeline.order
|
||||||
.map((id) => this.timeline.statuses.get(id))
|
.filter((id) => this.timeline.visibleStatusIds.has(id))
|
||||||
|
.map((id) => useStatusesStore().allStatuses.get(id))
|
||||||
.filter(({ pinned }) => (this.skipPinned ? !pinned : true))
|
.filter(({ pinned }) => (this.skipPinned ? !pinned : true))
|
||||||
},
|
},
|
||||||
newStatusCount() {
|
newStatusCount() {
|
||||||
|
|
@ -98,12 +100,12 @@ const Timeline = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
statusesToDisplay() {
|
statusesToDisplay() {
|
||||||
const amount = this.timeline.visibleStatusesIds.size
|
const amount = this.timeline.visibleStatusIds.size
|
||||||
const statusesPerSide = Math.ceil(Math.max(3, window.innerHeight / 80))
|
const statusesPerSide = Math.ceil(Math.max(3, window.innerHeight / 80))
|
||||||
const min = Math.max(0, this.virtualScrollIndex - statusesPerSide)
|
const min = Math.max(0, this.virtualScrollIndex - statusesPerSide)
|
||||||
const max = Math.min(amount, this.virtualScrollIndex + statusesPerSide)
|
const max = Math.min(amount, this.virtualScrollIndex + statusesPerSide)
|
||||||
return new Set(
|
return new Set(
|
||||||
[...this.timeline.visibleStatusesIds.keys()].slice(min, max),
|
this.timeline.order.slice(min, max),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
virtualScrollingEnabled() {
|
virtualScrollingEnabled() {
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
<Timeline
|
<Timeline
|
||||||
key="media"
|
key="media"
|
||||||
:label="$t('user_card.media')"
|
:label="$t('user_card.media')"
|
||||||
:disabled="!media.visibleStatusesIds.size"
|
:disabled="media.visibleStatusIds.size === 0"
|
||||||
:title="$t('user_card.media')"
|
:title="$t('user_card.media')"
|
||||||
:timeline-ref="{ name: 'media', argument: userId }"
|
:timeline-ref="{ name: 'media', argument: userId }"
|
||||||
embedded
|
embedded
|
||||||
|
|
@ -92,7 +92,7 @@
|
||||||
v-if="favoritesTabVisible"
|
v-if="favoritesTabVisible"
|
||||||
key="favorites"
|
key="favorites"
|
||||||
:label="$t('user_card.favorites')"
|
:label="$t('user_card.favorites')"
|
||||||
:disabled="!favorites.visibleStatusesIds.size"
|
:disabled="favorites.visibleStatusIds.size === 0"
|
||||||
:title="$t('user_card.favorites')"
|
:title="$t('user_card.favorites')"
|
||||||
:timeline-ref="{ name: 'favorites', argument: userId }"
|
:timeline-ref="{ name: 'favorites', argument: userId }"
|
||||||
:argument="isUs ? undefined : userId"
|
:argument="isUs ? undefined : userId"
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const REPLY_VISIBILITY_TIMELINES = new Set([
|
||||||
|
|
||||||
const fetchAndUpdate = (
|
const fetchAndUpdate = (
|
||||||
{ timeline, argument, credentials },
|
{ timeline, argument, credentials },
|
||||||
{ maxId, sinceId, older = false, showImmediately = false },
|
{ older = false, showImmediately = false },
|
||||||
) => {
|
) => {
|
||||||
timeline.loading = true
|
timeline.loading = true
|
||||||
const { hideMutedPosts, replyVisibility } =
|
const { hideMutedPosts, replyVisibility } =
|
||||||
|
|
@ -31,13 +31,9 @@ const fetchAndUpdate = (
|
||||||
|
|
||||||
if (older) {
|
if (older) {
|
||||||
// When minId = 0 we need to fetch without maxId param
|
// When minId = 0 we need to fetch without maxId param
|
||||||
args.maxId = maxId || timeline.minId || null
|
args.maxId = timeline.minId || null
|
||||||
} else {
|
} else {
|
||||||
if (sinceId === undefined) {
|
args.sinceId = timeline.maxId || null
|
||||||
args.sinceId = timeline.maxId
|
|
||||||
} else if (sinceId !== null) {
|
|
||||||
args.sinceId = sinceId
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args.withMuted = !hideMutedPosts
|
args.withMuted = !hideMutedPosts
|
||||||
|
|
@ -45,7 +41,7 @@ const fetchAndUpdate = (
|
||||||
args.replyVisibility = replyVisibility
|
args.replyVisibility = replyVisibility
|
||||||
}
|
}
|
||||||
|
|
||||||
const numStatusesBeforeFetch = timeline.statuses.size
|
const numStatusesBeforeFetch = timeline.statusIds.size
|
||||||
|
|
||||||
return fetchTimeline(args)
|
return fetchTimeline(args)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
|
@ -62,10 +58,12 @@ const fetchAndUpdate = (
|
||||||
const processed = useStatusesStore()
|
const processed = useStatusesStore()
|
||||||
.addNewStatuses({ statuses, timestamp })
|
.addNewStatuses({ statuses, timestamp })
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
|
.map(({ id }) => id)
|
||||||
|
|
||||||
useTimelinesStore().addStatusesToTimeline(timeline.name, argument, {
|
useTimelinesStore().addStatusesToTimeline(timeline.name, argument, {
|
||||||
statuses: processed,
|
statuses: processed,
|
||||||
showImmediately,
|
showImmediately,
|
||||||
|
older,
|
||||||
pagination,
|
pagination,
|
||||||
})
|
})
|
||||||
return { statuses, pagination }
|
return { statuses, pagination }
|
||||||
|
|
@ -95,8 +93,6 @@ const timelineFetcher = (timeline, argument, credentials) => {
|
||||||
|
|
||||||
const boundFetchAndUpdate = ({
|
const boundFetchAndUpdate = ({
|
||||||
showImmediately,
|
showImmediately,
|
||||||
maxId,
|
|
||||||
sinceId,
|
|
||||||
older,
|
older,
|
||||||
} = {}) =>
|
} = {}) =>
|
||||||
fetchAndUpdate(
|
fetchAndUpdate(
|
||||||
|
|
@ -106,8 +102,6 @@ const timelineFetcher = (timeline, argument, credentials) => {
|
||||||
credentials,
|
credentials,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
maxId,
|
|
||||||
sinceId,
|
|
||||||
older,
|
older,
|
||||||
showImmediately,
|
showImmediately,
|
||||||
},
|
},
|
||||||
|
|
@ -117,7 +111,7 @@ const timelineFetcher = (timeline, argument, credentials) => {
|
||||||
if (state.interval) throw new Error('Interval already exists!')
|
if (state.interval) throw new Error('Interval already exists!')
|
||||||
|
|
||||||
boundFetchAndUpdate({
|
boundFetchAndUpdate({
|
||||||
showImmediately: timeline.visibleStatusesIds.size === 0,
|
showImmediately: timeline.visibleStatusIds.size === 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
state.interval = promiseInterval(boundFetchAndUpdate, 10000)
|
state.interval = promiseInterval(boundFetchAndUpdate, 10000)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import {
|
|
||||||
fetchScrobbles,
|
|
||||||
} from 'src/api/public.js'
|
|
||||||
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
|
import { useUsersStore } from 'src/stores/users.js'
|
||||||
|
|
||||||
|
import { fetchScrobbles } from 'src/api/public.js'
|
||||||
|
|
||||||
export const defaultState = () => ({
|
export const defaultState = () => ({
|
||||||
scrobblesNextFetch: new Map(),
|
scrobblesNextFetch: new Map(),
|
||||||
|
|
@ -13,7 +14,7 @@ export const useScrobblesStore = defineStore('scrobbles', {
|
||||||
actions: {
|
actions: {
|
||||||
getLatestScrobble(userId) {
|
getLatestScrobble(userId) {
|
||||||
const scrobblesSupport =
|
const scrobblesSupport =
|
||||||
useInstanceCapabilitiesStore().pleromaScrobblesAvailable
|
useInstanceCapabilitiesStore().pleromaScrobblesAvailable
|
||||||
|
|
||||||
if (!scrobblesSupport) {
|
if (!scrobblesSupport) {
|
||||||
return
|
return
|
||||||
|
|
@ -29,12 +30,12 @@ export const useScrobblesStore = defineStore('scrobbles', {
|
||||||
.then(({ data: scrobbles }) => {
|
.then(({ data: scrobbles }) => {
|
||||||
useUsersStore().findUser(userId).latestScrobble = scrobbles[0]
|
useUsersStore().findUser(userId).latestScrobble = scrobbles[0]
|
||||||
|
|
||||||
this.scrobblesNextFetch.set(user.id, Date.now() + 60 * 1000)
|
this.scrobblesNextFetch.set(userId, Date.now() + 60 * 1000)
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
useInstanceCapabilitiesStore().set('pleromaScrobblesAvailable', false)
|
useInstanceCapabilitiesStore().set('pleromaScrobblesAvailable', false)
|
||||||
console.warn('cannot fetch scrobbles', e)
|
console.warn('cannot fetch scrobbles', e)
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
55
src/stores/search.js
Normal file
55
src/stores/search.js
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
import { useStatusesStore } from 'src/stores/statuses.js'
|
||||||
|
import { useUsersStore } from 'src/stores/users.js'
|
||||||
|
|
||||||
|
import { search2 } from 'src/api/public.js'
|
||||||
|
|
||||||
|
export const useSearchStore = defineStore('search', {
|
||||||
|
actions: {
|
||||||
|
async search({ q, resolve, limit, offset, following, type }) {
|
||||||
|
const { data, ...rest } = await search2({
|
||||||
|
q,
|
||||||
|
resolve,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
following,
|
||||||
|
type,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { accounts, statuses } = data
|
||||||
|
|
||||||
|
useUsersStore().addNewUsers({
|
||||||
|
...rest,
|
||||||
|
data: accounts,
|
||||||
|
})
|
||||||
|
|
||||||
|
useStatusesStore().addNewStatuses({
|
||||||
|
...rest,
|
||||||
|
statuses,
|
||||||
|
})
|
||||||
|
|
||||||
|
const output = {}
|
||||||
|
output.statuses = statuses.map((s) =>
|
||||||
|
useStatusesStore().allStatuses.get(s.id),
|
||||||
|
)
|
||||||
|
output.accounts = accounts.map((s) => useUsersStore().findUser(s.id))
|
||||||
|
return output
|
||||||
|
},
|
||||||
|
|
||||||
|
// Search
|
||||||
|
searchUsers({ query }) {
|
||||||
|
return searchUsers({
|
||||||
|
query,
|
||||||
|
credentials: useOAuthStore().token,
|
||||||
|
}).then((result) => {
|
||||||
|
const { data } = result
|
||||||
|
useUsersStore().addNewUsers(result)
|
||||||
|
|
||||||
|
return data.map((s) => useUsersStore().findUser(s.id))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
import { useStreamingStore } from 'src/stores/streaming.js'
|
import { useStreamingStore } from 'src/stores/streaming.js'
|
||||||
|
|
@ -240,6 +239,10 @@ export const useStatusesStore = defineStore('statuses', {
|
||||||
const status = this.allStatuses.get(id)
|
const status = this.allStatuses.get(id)
|
||||||
status.emoji_reactions = emojiReactions
|
status.emoji_reactions = emojiReactions
|
||||||
},
|
},
|
||||||
|
updateStatusWithPoll(id, poll) {
|
||||||
|
const status = this.allStatuses.get(id)
|
||||||
|
status.poll = poll
|
||||||
|
},
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
requestInteract({ name, id, optimisticCall, apiCall, argument, value }) {
|
requestInteract({ name, id, optimisticCall, apiCall, argument, value }) {
|
||||||
|
|
@ -524,49 +527,20 @@ export const useStatusesStore = defineStore('statuses', {
|
||||||
|
|
||||||
// For when blocking a user
|
// For when blocking a user
|
||||||
wipeUserStatuses(userId) {
|
wipeUserStatuses(userId) {
|
||||||
|
const removed = new Set()
|
||||||
this.allStatuses.forEach((status) => {
|
this.allStatuses.forEach((status) => {
|
||||||
if (status.user.id === userId) {
|
if (status.user.id === userId) {
|
||||||
this.allStatuses.delete(status.id)
|
this.allStatuses.delete(status.id)
|
||||||
|
|
||||||
|
removed.add(status.id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
return removed
|
||||||
},
|
},
|
||||||
|
|
||||||
// Search
|
// Misc
|
||||||
search({ q, resolve, limit, offset, following, type }) {
|
|
||||||
return search2({
|
|
||||||
q,
|
|
||||||
resolve,
|
|
||||||
limit,
|
|
||||||
offset,
|
|
||||||
following,
|
|
||||||
type,
|
|
||||||
credentials: useOAuthStore().token,
|
|
||||||
}).then((result) => {
|
|
||||||
const { data, ...rest } = result
|
|
||||||
useUsersStore().addNewUsers({
|
|
||||||
...rest,
|
|
||||||
data: data.accounts,
|
|
||||||
})
|
|
||||||
|
|
||||||
useUsersStore().addNewUsers({
|
|
||||||
...rest,
|
|
||||||
data: data.statuses.map((s) => s.user).filter(Boolean),
|
|
||||||
})
|
|
||||||
|
|
||||||
this.addNewStatuses({
|
|
||||||
statuses: data.statuses,
|
|
||||||
})
|
|
||||||
|
|
||||||
data.statuses = data.statuses.map((s) => this.allStatuses.get(s.id))
|
|
||||||
return data
|
|
||||||
})
|
|
||||||
},
|
|
||||||
setVirtualHeight({ statusId, height }) {
|
setVirtualHeight({ statusId, height }) {
|
||||||
this.allStatuses.get(statusId).virtualHeight = height
|
this.allStatuses.get(statusId).virtualHeight = height
|
||||||
},
|
},
|
||||||
updateStatusWithPoll({ id, poll }) {
|
|
||||||
const status = this.allStatuses.get(id)
|
|
||||||
status.poll = poll
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -12,16 +12,17 @@ import timelineFetcher from 'src/services/timeline_fetcher/timeline_fetcher.serv
|
||||||
const emptyTl = (name, argument = null) => {
|
const emptyTl = (name, argument = null) => {
|
||||||
const result = {
|
const result = {
|
||||||
name,
|
name,
|
||||||
statuses: new Map(),
|
order: [],
|
||||||
visibleStatusesIds: new Set(),
|
statusIds: new Set(),
|
||||||
|
visibleStatusIds: new Set(),
|
||||||
newStatusCount: 0,
|
newStatusCount: 0,
|
||||||
maxId: '',
|
maxId: '',
|
||||||
minId: '',
|
minId: '',
|
||||||
minVisibleId: '',
|
|
||||||
loading: false,
|
loading: false,
|
||||||
streaming: false,
|
streaming: false,
|
||||||
flushMarker: 0,
|
flushMarker: 0,
|
||||||
fetcher: null,
|
fetcher: null,
|
||||||
|
socket: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
const property = ARGUMENT_MAP[name]
|
const property = ARGUMENT_MAP[name]
|
||||||
|
|
@ -88,6 +89,11 @@ export const useTimelinesStore = defineStore('timelines', {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const property = ARGUMENT_MAP[timelineName]
|
||||||
|
if (property) {
|
||||||
|
timeline[property] = argument
|
||||||
|
}
|
||||||
|
|
||||||
timeline.fetcher = timelineFetcher(
|
timeline.fetcher = timelineFetcher(
|
||||||
timeline,
|
timeline,
|
||||||
argument,
|
argument,
|
||||||
|
|
@ -156,7 +162,11 @@ export const useTimelinesStore = defineStore('timelines', {
|
||||||
},
|
},
|
||||||
deactivateAll() {
|
deactivateAll() {
|
||||||
TIMELINES.forEach((name) => {
|
TIMELINES.forEach((name) => {
|
||||||
this.deactivate(name, true)
|
try {
|
||||||
|
this.deactivate(name, true)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Failed to deactivate timeline ${name}`)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -169,7 +179,7 @@ export const useTimelinesStore = defineStore('timelines', {
|
||||||
showImmediately = false,
|
showImmediately = false,
|
||||||
noIdUpdate = false,
|
noIdUpdate = false,
|
||||||
pagination = {},
|
pagination = {},
|
||||||
nested = false,
|
older = false
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if (statuses.length === 0) return
|
if (statuses.length === 0) return
|
||||||
|
|
@ -179,7 +189,7 @@ export const useTimelinesStore = defineStore('timelines', {
|
||||||
// user. I.e. opening different user profiles makes request which could
|
// user. I.e. opening different user profiles makes request which could
|
||||||
// return data late after user already viewing different user profile
|
// return data late after user already viewing different user profile
|
||||||
// Same can happen with tags etc.
|
// Same can happen with tags etc.
|
||||||
const property = ARGUMENT_MAP[name]
|
const property = ARGUMENT_MAP[timelineName]
|
||||||
|
|
||||||
if (property && timeline[property] !== argument) {
|
if (property && timeline[property] !== argument) {
|
||||||
return
|
return
|
||||||
|
|
@ -188,59 +198,36 @@ export const useTimelinesStore = defineStore('timelines', {
|
||||||
if (!noIdUpdate) {
|
if (!noIdUpdate) {
|
||||||
this.updateTimelineExtremes(
|
this.updateTimelineExtremes(
|
||||||
timeline,
|
timeline,
|
||||||
statuses.map((x) => x.id),
|
|
||||||
pagination,
|
pagination,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
statuses.forEach((status) => {
|
const filtered = statuses.filter((id) => !timeline.statusIds.has(id))
|
||||||
const isNew = !timeline.statuses.has(status.id)
|
if (older) {
|
||||||
timeline.statuses.set(status.id, status)
|
timeline.order.push(...filtered)
|
||||||
|
} else {
|
||||||
|
timeline.order.unshift(...filtered)
|
||||||
|
}
|
||||||
|
|
||||||
|
statuses.forEach((statusId) => {
|
||||||
|
const isNew = !timeline.statusIds.has(statusId)
|
||||||
|
timeline.statusIds.add(statusId)
|
||||||
|
|
||||||
if (isNew) {
|
if (isNew) {
|
||||||
if (showImmediately) {
|
if (showImmediately) {
|
||||||
// Add it directly to the visibleStatuses, don't change
|
// Add it directly to the visibleStatuses, don't change
|
||||||
// newStatusCount
|
// newStatusCount
|
||||||
timeline.visibleStatusesIds.add(status.id)
|
timeline.visibleStatusIds.add(statusId)
|
||||||
} else {
|
} else {
|
||||||
// Just change newStatuscount
|
// Just change newStatuscount
|
||||||
timeline.newStatusCount += 1
|
timeline.newStatusCount += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nested) return
|
|
||||||
// We are mentioned in a post
|
|
||||||
if (
|
|
||||||
status.type === 'status' &&
|
|
||||||
status.attentions.some(
|
|
||||||
({ id }) => id === useUsersStore().currentUser?.id,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
// Add the mention to the mentions timeline
|
|
||||||
if (timeline !== this.mentions) {
|
|
||||||
this.addStatusesToTimeline('mentions', null, {
|
|
||||||
statuses: [status],
|
|
||||||
nested: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.visibility === 'direct') {
|
|
||||||
if (timeline !== this.dms) {
|
|
||||||
this.addStatusesToTimeline('dms', null, {
|
|
||||||
statuses: [status],
|
|
||||||
nested: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onStreamMessage(timeline, argument, event) {
|
onStreamMessage(timeline, argument, event) {
|
||||||
// This relies on statuses store to process this event first
|
|
||||||
const status = useStatusesStore().allStatuses.get(event.data.status.id)
|
|
||||||
|
|
||||||
this.addStatusesToTimeline(timeline, argument, {
|
this.addStatusesToTimeline(timeline, argument, {
|
||||||
statuses: [status],
|
statuses: [event.data.status.id],
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -278,10 +265,10 @@ export const useTimelinesStore = defineStore('timelines', {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Queues & Timeline manip
|
// Queues & Timeline manip
|
||||||
updateTimelineExtremes(timeline, statuses, pagination = {}) {
|
updateTimelineExtremes(timeline, pagination = {}) {
|
||||||
// Can't use Math.min/max because it doesn't work with string (duh)
|
// Can't use Math.min/max because it doesn't work with string (duh)
|
||||||
const minNew = pagination.maxId ?? min(...statuses) ?? ''
|
const minNew = pagination.maxId ?? last(timeline.order) ?? ''
|
||||||
const maxNew = pagination.minId ?? max(...statuses) ?? ''
|
const maxNew = pagination.minId ?? first(timeline.order) ?? ''
|
||||||
|
|
||||||
const newer = maxNew > timeline.maxId
|
const newer = maxNew > timeline.maxId
|
||||||
const older = minNew < timeline.minId
|
const older = minNew < timeline.minId
|
||||||
|
|
@ -292,20 +279,17 @@ export const useTimelinesStore = defineStore('timelines', {
|
||||||
if (older || timeline.minId === '') {
|
if (older || timeline.minId === '') {
|
||||||
timeline.minId = minNew
|
timeline.minId = minNew
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.syncOrder(timeline)
|
||||||
},
|
},
|
||||||
showNewStatuses(timelineName) {
|
showNewStatuses(timelineName) {
|
||||||
const timeline = this[timelineName]
|
const timeline = this[timelineName]
|
||||||
|
|
||||||
timeline.newStatusCount = 0
|
timeline.newStatusCount = 0
|
||||||
|
timeline.visibleStatusIds = new Set([...timeline.statusIds])
|
||||||
timeline.visibleStatusesIds = new Set(
|
},
|
||||||
[...timeline.statuses.keys()].slice(0, 50),
|
syncOrder(timeline) {
|
||||||
)
|
timeline.order = timeline.order.filter((id) => timeline.statusIds.has(id))
|
||||||
timeline.minVisibleId = last(timeline.visibleStatusesIds.keys())
|
|
||||||
timeline.minId = ''
|
|
||||||
timeline.maxId = ''
|
|
||||||
|
|
||||||
this.updateTimelineExtremes(timeline, [...timeline.statuses.keys()])
|
|
||||||
},
|
},
|
||||||
queueFlush(timeline, id) {
|
queueFlush(timeline, id) {
|
||||||
this[timeline].flushMarker = id
|
this[timeline].flushMarker = id
|
||||||
|
|
@ -317,23 +301,16 @@ export const useTimelinesStore = defineStore('timelines', {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
wipeUserStatuses(userId) {
|
wipeStatuses(ids) {
|
||||||
TIMELINES.forEach((timelineName) => {
|
TIMELINES.forEach((timelineName) => {
|
||||||
const timeline = this.timelines[timelineName]
|
const timeline = this[timelineName]
|
||||||
|
|
||||||
timeline.statuses
|
ids.forEach((id) => {
|
||||||
.values()
|
timeline.statusIds.delete(id)
|
||||||
.filter(({ user }) => user.id === userId)
|
timeline.visibleStatusIds.delete(id)
|
||||||
.forEach(({ id }) => {
|
})
|
||||||
timeline.statuses.delete(id)
|
|
||||||
timeline.visibleStatusesIds.delete(id)
|
this.syncOrder(timeline)
|
||||||
})
|
|
||||||
timeline.minVisibleId =
|
|
||||||
timeline.visibleStatusesIds.size > 0
|
|
||||||
? last(timeline.visibleStatusesIds).id
|
|
||||||
: 0
|
|
||||||
timeline.maxId =
|
|
||||||
timeline.statuses.length > 0 ? first(timeline.statuses).id : 0
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -746,17 +746,6 @@ export const useUsersStore = defineStore('users', {
|
||||||
useInterfaceStore().onLogout()
|
useInterfaceStore().onLogout()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// Search
|
|
||||||
searchUsers({ query }) {
|
|
||||||
return searchUsers({
|
|
||||||
query,
|
|
||||||
credentials: useOAuthStore().token,
|
|
||||||
}).then(({ data: users }) => {
|
|
||||||
this.addNewUsers(users)
|
|
||||||
return users
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
persist: {
|
persist: {
|
||||||
paths: ['lastLoginName'],
|
paths: ['lastLoginName'],
|
||||||
|
|
|
||||||
|
|
@ -51,125 +51,12 @@ const externalProfileStore = createStore({
|
||||||
mutations,
|
mutations,
|
||||||
actions,
|
actions,
|
||||||
getters: testGetters,
|
getters: testGetters,
|
||||||
state: {
|
|
||||||
interface: {
|
|
||||||
browserSupport: '',
|
|
||||||
},
|
|
||||||
instance: {
|
|
||||||
hideUserStats: true,
|
|
||||||
},
|
|
||||||
statuses: {
|
|
||||||
timelines: {
|
|
||||||
user: {
|
|
||||||
statuses: [],
|
|
||||||
statusesObject: {},
|
|
||||||
faves: [],
|
|
||||||
visibleStatuses: [],
|
|
||||||
visibleStatusesObject: {},
|
|
||||||
newStatusCount: 0,
|
|
||||||
maxId: 0,
|
|
||||||
minVisibleId: 0,
|
|
||||||
loading: false,
|
|
||||||
followers: [],
|
|
||||||
friends: [],
|
|
||||||
viewing: 'statuses',
|
|
||||||
userId: 100,
|
|
||||||
flushMarker: 0,
|
|
||||||
},
|
|
||||||
media: {
|
|
||||||
statuses: [],
|
|
||||||
statusesObject: {},
|
|
||||||
faves: [],
|
|
||||||
visibleStatuses: [],
|
|
||||||
visibleStatusesObject: {},
|
|
||||||
newStatusCount: 0,
|
|
||||||
maxId: 0,
|
|
||||||
minVisibleId: 0,
|
|
||||||
loading: false,
|
|
||||||
followers: [],
|
|
||||||
friends: [],
|
|
||||||
viewing: 'statuses',
|
|
||||||
userId: 100,
|
|
||||||
flushMarker: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
users: {
|
|
||||||
currentUser: {
|
|
||||||
credentials: '',
|
|
||||||
},
|
|
||||||
usersObject: { 100: extUser },
|
|
||||||
usersByNameObject: {},
|
|
||||||
users: [extUser],
|
|
||||||
relationships: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const localProfileStore = createStore({
|
const localProfileStore = createStore({
|
||||||
mutations,
|
mutations,
|
||||||
actions,
|
actions,
|
||||||
getters: testGetters,
|
getters: testGetters,
|
||||||
state: {
|
|
||||||
interface: {
|
|
||||||
browserSupport: '',
|
|
||||||
},
|
|
||||||
config: {
|
|
||||||
colors: '',
|
|
||||||
highlight: {},
|
|
||||||
customTheme: {
|
|
||||||
colors: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
instance: {
|
|
||||||
hideUserStats: true,
|
|
||||||
},
|
|
||||||
statuses: {
|
|
||||||
timelines: {
|
|
||||||
user: {
|
|
||||||
statuses: [],
|
|
||||||
statusesObject: {},
|
|
||||||
faves: [],
|
|
||||||
visibleStatuses: [],
|
|
||||||
visibleStatusesObject: {},
|
|
||||||
newStatusCount: 0,
|
|
||||||
maxId: 0,
|
|
||||||
minVisibleId: 0,
|
|
||||||
loading: false,
|
|
||||||
followers: [],
|
|
||||||
friends: [],
|
|
||||||
viewing: 'statuses',
|
|
||||||
userId: 100,
|
|
||||||
flushMarker: 0,
|
|
||||||
},
|
|
||||||
media: {
|
|
||||||
statuses: [],
|
|
||||||
statusesObject: {},
|
|
||||||
faves: [],
|
|
||||||
visibleStatuses: [],
|
|
||||||
visibleStatusesObject: {},
|
|
||||||
newStatusCount: 0,
|
|
||||||
maxId: 0,
|
|
||||||
minVisibleId: 0,
|
|
||||||
loading: false,
|
|
||||||
followers: [],
|
|
||||||
friends: [],
|
|
||||||
viewing: 'statuses',
|
|
||||||
userId: 100,
|
|
||||||
flushMarker: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
users: {
|
|
||||||
currentUser: {
|
|
||||||
credentials: '',
|
|
||||||
},
|
|
||||||
usersObject: { 100: localUser },
|
|
||||||
usersByNameObject: { testuser: localUser },
|
|
||||||
users: [localUser],
|
|
||||||
relationships: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// https://github.com/vuejs/test-utils/issues/1382
|
// https://github.com/vuejs/test-utils/issues/1382
|
||||||
|
|
|
||||||
|
|
@ -626,8 +626,9 @@ describe('Statuses store', () => {
|
||||||
timestamp: 1,
|
timestamp: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
store.wipeUserStatuses('u19')
|
const result = store.wipeUserStatuses('u19')
|
||||||
|
|
||||||
expect(store.allStatuses).to.have.length(19)
|
expect(store.allStatuses).to.have.length(19)
|
||||||
|
expect(result).to.eql(new Set(['s19']))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
358
test/unit/specs/stores/timelines.spec.js
Normal file
358
test/unit/specs/stores/timelines.spec.js
Normal file
|
|
@ -0,0 +1,358 @@
|
||||||
|
import { createTestingPinia } from '@pinia/testing'
|
||||||
|
import { setActivePinia } from 'pinia'
|
||||||
|
|
||||||
|
import { useStatusesStore } from 'src/stores/statuses.js'
|
||||||
|
import { useTimelinesStore } from 'src/stores/timelines.js'
|
||||||
|
import { useStreamingStore } from 'src/stores/streaming.js'
|
||||||
|
|
||||||
|
describe('Timelines store', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.useFakeTimers()
|
||||||
|
setActivePinia(createTestingPinia({ stubActions: false }))
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
useTimelinesStore().deactivateAll()
|
||||||
|
vi.useRealTimers()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('activate', () => {
|
||||||
|
it('streamable', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const sub = vi.fn()
|
||||||
|
useStreamingStore().addSubscriber = sub
|
||||||
|
|
||||||
|
console.log(store.activate)
|
||||||
|
store.activate('friends', undefined, true)
|
||||||
|
|
||||||
|
expect(sub).to.have.been.called
|
||||||
|
expect(store.friends.fetcher).to.not.be.null
|
||||||
|
expect(store.friends.socket).to.not.be.null
|
||||||
|
})
|
||||||
|
|
||||||
|
it('non-streamable', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const sub = vi.fn()
|
||||||
|
useStreamingStore().addSubscriber = sub
|
||||||
|
|
||||||
|
console.log(store.activate)
|
||||||
|
store.activate('user', '1')
|
||||||
|
|
||||||
|
expect(sub).to.not.have.been.called
|
||||||
|
expect(store.user.fetcher).to.not.be.null
|
||||||
|
expect(store.user.socket).to.be.null
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('deactivate', () => {
|
||||||
|
it('streamable', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const unsub = vi.fn()
|
||||||
|
useStreamingStore().removeSubscriber = unsub
|
||||||
|
|
||||||
|
store.activate('friends', undefined, true)
|
||||||
|
// Checking so that they were set properly before
|
||||||
|
// since reset changes them to ''
|
||||||
|
store.friends.maxId = '3'
|
||||||
|
store.friends.minId = '4'
|
||||||
|
store.friends.statusIds = new Set(['3','4'])
|
||||||
|
store.friends.visibleStausIds = new Set(['3','4'])
|
||||||
|
store.deactivate('friends', true)
|
||||||
|
|
||||||
|
expect(unsub).to.have.been.called
|
||||||
|
expect(store.friends.fetcher).to.be.null
|
||||||
|
expect(store.friends.socket).to.be.null
|
||||||
|
expect(store.friends.statusIds).to.have.length(0)
|
||||||
|
expect(store.friends.visibleStatusIds).to.have.length(0)
|
||||||
|
expect(store.friends).to.have.property('maxId', '')
|
||||||
|
expect(store.friends).to.have.property('minId', '')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('non-streamable', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const unsub = vi.fn()
|
||||||
|
useStreamingStore().removeSubscriber = unsub
|
||||||
|
|
||||||
|
store.activate('user', '1')
|
||||||
|
// Checking so that they were set properly before
|
||||||
|
// since reset changes them to ''
|
||||||
|
store.user.maxId = '3'
|
||||||
|
store.user.minId = '4'
|
||||||
|
store.user.statusIds = new Set(['3','4'])
|
||||||
|
store.user.visibleStausIds = new Set(['3','4'])
|
||||||
|
store.deactivate('user')
|
||||||
|
|
||||||
|
expect(unsub).to.not.have.been.called
|
||||||
|
expect(store.user.fetcher).to.be.null
|
||||||
|
expect(store.user.socket).to.be.null
|
||||||
|
expect(store.user.statusIds).to.have.length(0)
|
||||||
|
expect(store.user.visibleStatusIds).to.have.length(0)
|
||||||
|
expect(store.user).to.have.property('maxId', '')
|
||||||
|
expect(store.user).to.have.property('minId', '')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('updateTimelineExtremes', () => {
|
||||||
|
it('should derive extremes from data', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const timeline = useTimelinesStore().friends
|
||||||
|
timeline.order = ['4','1','3','2']
|
||||||
|
timeline.statusesIds = new Set(timeline.order)
|
||||||
|
store.updateTimelineExtremes(timeline)
|
||||||
|
|
||||||
|
expect(store.friends).to.have.property('maxId', '4')
|
||||||
|
expect(store.friends).to.have.property('minId', '2')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should use extremes from pagination', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const timeline = useTimelinesStore().friends
|
||||||
|
store.updateTimelineExtremes(
|
||||||
|
timeline,
|
||||||
|
{ maxId: '1', minId: '2' }
|
||||||
|
)
|
||||||
|
|
||||||
|
// Min and max are swapped!
|
||||||
|
expect(store.friends).to.have.property('maxId', '2')
|
||||||
|
expect(store.friends).to.have.property('minId', '1')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('addStatusesToTimeline', () => {
|
||||||
|
it('adds the status to the given timeline', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const statuses = ['1','2','3']
|
||||||
|
|
||||||
|
store.activate('list', '1')
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'1',
|
||||||
|
{
|
||||||
|
statuses,
|
||||||
|
pagination: { minId: '1', maxId: '3' }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(store.list.order).to.eql(statuses)
|
||||||
|
expect(store.list.statusIds).to.eql(new Set(statuses))
|
||||||
|
expect(store.list.visibleStatusIds).to.eql(new Set())
|
||||||
|
expect(store.list.newStatusCount).to.equal(3)
|
||||||
|
expect(store.list).to.have.property('maxId', '1')
|
||||||
|
expect(store.list).to.have.property('minId', '3')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('ignores duplicates', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const statuses = ['1','2','3']
|
||||||
|
|
||||||
|
store.activate('list', '1')
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'1',
|
||||||
|
{
|
||||||
|
statuses,
|
||||||
|
pagination: { minId: '1', maxId: '3' }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'1',
|
||||||
|
{
|
||||||
|
statuses,
|
||||||
|
pagination: { minId: '1', maxId: '3' }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(store.list.order).to.eql(statuses)
|
||||||
|
expect(store.list.statusIds).to.eql(new Set(statuses))
|
||||||
|
expect(store.list.visibleStatusIds).to.eql(new Set())
|
||||||
|
expect(store.list.newStatusCount).to.equal(3)
|
||||||
|
expect(store.list).to.have.property('maxId', '1')
|
||||||
|
expect(store.list).to.have.property('minId', '3')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('adds the status the given timeline, directly visible', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const statuses = ['1','2','3']
|
||||||
|
|
||||||
|
store.activate('list', '1')
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'1',
|
||||||
|
{
|
||||||
|
statuses,
|
||||||
|
showImmediately: true,
|
||||||
|
pagination: { minId: '1', maxId: '3' }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(store.list.order).to.eql(statuses)
|
||||||
|
expect(store.list.statusIds).to.eql(new Set(statuses))
|
||||||
|
expect(store.list.visibleStatusIds).to.eql(new Set(statuses))
|
||||||
|
expect(store.list.newStatusCount).to.equal(0)
|
||||||
|
expect(store.list).to.have.property('maxId', '1')
|
||||||
|
expect(store.list).to.have.property('minId', '3')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not update the maxId when the noIdUpdate flag is set', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const statuses = ['1','2','3']
|
||||||
|
|
||||||
|
store.activate('list', '1')
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'1',
|
||||||
|
{
|
||||||
|
statuses,
|
||||||
|
noIdUpdate: true,
|
||||||
|
pagination: { minId: '1', maxId: '3' }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(store.list.order).to.eql(statuses)
|
||||||
|
expect(store.list.statusIds).to.eql(new Set(statuses))
|
||||||
|
expect(store.list.visibleStatusIds).to.eql(new Set())
|
||||||
|
expect(store.list.newStatusCount).to.equal(3)
|
||||||
|
expect(store.list).to.have.property('maxId', '')
|
||||||
|
expect(store.list).to.have.property('minId', '')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not update timeline if it belongs to a different arugment', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const statuses = ['1','2','3']
|
||||||
|
|
||||||
|
store.activate('list', '1')
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'2',
|
||||||
|
{
|
||||||
|
statuses,
|
||||||
|
noIdUpdate: true,
|
||||||
|
pagination: { minId: '1', maxId: '3' }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(store.list.order).to.eql([])
|
||||||
|
expect(store.list.statusIds).to.eql(new Set())
|
||||||
|
expect(store.list.visibleStatusIds).to.eql(new Set())
|
||||||
|
expect(store.list.newStatusCount).to.equal(0)
|
||||||
|
expect(store.list).to.have.property('maxId', '')
|
||||||
|
expect(store.list).to.have.property('minId', '')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('prepends timeline with new statuses', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const statuses1 = ['3','2','1']
|
||||||
|
const statuses2 = ['6','5','4']
|
||||||
|
|
||||||
|
store.activate('list', '1')
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'1',
|
||||||
|
{
|
||||||
|
statuses: statuses1,
|
||||||
|
pagination: { minId: '3', maxId: '1' }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'1',
|
||||||
|
{
|
||||||
|
statuses: statuses2,
|
||||||
|
pagination: { minId: '6', maxId: '4' }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const newOrder = [...statuses2, ...statuses1]
|
||||||
|
expect(store.list.order).to.eql(newOrder)
|
||||||
|
expect(store.list.statusIds).to.eql(new Set(newOrder))
|
||||||
|
expect(store.list.visibleStatusIds).to.eql(new Set())
|
||||||
|
expect(store.list.newStatusCount).to.equal(6)
|
||||||
|
expect(store.list).to.have.property('maxId', '6')
|
||||||
|
expect(store.list).to.have.property('minId', '1')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appends timeline with new statuses if fetching older', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const statuses1 = ['6','5','4']
|
||||||
|
const statuses2 = ['3','2','1']
|
||||||
|
|
||||||
|
store.activate('list', '1')
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'1',
|
||||||
|
{
|
||||||
|
statuses: statuses1,
|
||||||
|
pagination: { minId: '6', maxId: '4' },
|
||||||
|
}
|
||||||
|
)
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'list',
|
||||||
|
'1',
|
||||||
|
{
|
||||||
|
statuses: statuses2,
|
||||||
|
pagination: { minId: '3', maxId: '1' },
|
||||||
|
older: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const newOrder = [...statuses1, ...statuses2]
|
||||||
|
expect(store.list.order).to.eql(newOrder)
|
||||||
|
expect(store.list.statusIds).to.eql(new Set(newOrder))
|
||||||
|
expect(store.list.visibleStatusIds).to.eql(new Set())
|
||||||
|
expect(store.list.newStatusCount).to.equal(6)
|
||||||
|
expect(store.list).to.have.property('maxId', '6')
|
||||||
|
expect(store.list).to.have.property('minId', '1')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('showNewStatuses', () => {
|
||||||
|
it('resets counter and makes all ids visible', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
const statuses = ['1','2','3']
|
||||||
|
|
||||||
|
store.activate('public')
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'public',
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
statuses,
|
||||||
|
pagination: { minId: '1', maxId: '3' }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(store.public.statusIds).to.eql(new Set(statuses))
|
||||||
|
expect(store.public.visibleStatusIds).to.eql(new Set())
|
||||||
|
expect(store.public.newStatusCount).to.equal(3)
|
||||||
|
store.showNewStatuses('public')
|
||||||
|
expect(store.public.visibleStatusIds).to.eql(new Set(statuses))
|
||||||
|
expect(store.public.newStatusCount).to.equal(0)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('wipeStatuses', () => {
|
||||||
|
it('clears all statuses', () => {
|
||||||
|
const store = useTimelinesStore()
|
||||||
|
|
||||||
|
store.activate('friends')
|
||||||
|
store.activate('public')
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'public',
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
statuses: ['1','2','3','0']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
store.addStatusesToTimeline(
|
||||||
|
'friends',
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
statuses: ['5','0','9','1']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
store.wipeStatuses(['0'])
|
||||||
|
expect(store.friends.statusIds).to.not.have.members('0')
|
||||||
|
expect(store.public.statusIds).to.not.have.members('0')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue