user profile work
This commit is contained in:
parent
cb25b392cf
commit
1f3b9a3905
7 changed files with 53 additions and 58 deletions
|
|
@ -115,6 +115,7 @@ export const fetchTimeline = ({
|
||||||
publicAndExternal: MASTODON_PUBLIC_TIMELINE,
|
publicAndExternal: MASTODON_PUBLIC_TIMELINE,
|
||||||
dms: MASTODON_DIRECT_MESSAGES_TIMELINE_URL,
|
dms: MASTODON_DIRECT_MESSAGES_TIMELINE_URL,
|
||||||
user: MASTODON_USER_TIMELINE_URL,
|
user: MASTODON_USER_TIMELINE_URL,
|
||||||
|
userPinned: MASTODON_USER_TIMELINE_URL,
|
||||||
media: MASTODON_USER_TIMELINE_URL,
|
media: MASTODON_USER_TIMELINE_URL,
|
||||||
list: MASTODON_LIST_TIMELINE_URL,
|
list: MASTODON_LIST_TIMELINE_URL,
|
||||||
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
|
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
|
||||||
|
|
@ -130,6 +131,7 @@ export const fetchTimeline = ({
|
||||||
|
|
||||||
const twoArgs = new Set([
|
const twoArgs = new Set([
|
||||||
'user',
|
'user',
|
||||||
|
'userPinned',
|
||||||
'media',
|
'media',
|
||||||
'list',
|
'list',
|
||||||
'publicFavorites',
|
'publicFavorites',
|
||||||
|
|
@ -147,6 +149,7 @@ export const fetchTimeline = ({
|
||||||
const id = (() => {
|
const id = (() => {
|
||||||
switch (timeline) {
|
switch (timeline) {
|
||||||
case 'user':
|
case 'user':
|
||||||
|
case 'userPinned':
|
||||||
case 'media':
|
case 'media':
|
||||||
return userId
|
return userId
|
||||||
case 'list':
|
case 'list':
|
||||||
|
|
@ -163,6 +166,9 @@ export const fetchTimeline = ({
|
||||||
if (timeline === 'media') {
|
if (timeline === 'media') {
|
||||||
params.onlyMedia = true
|
params.onlyMedia = true
|
||||||
}
|
}
|
||||||
|
if (timeline === 'userPinned') {
|
||||||
|
params.pinned = true
|
||||||
|
}
|
||||||
if (timeline === 'public') {
|
if (timeline === 'public') {
|
||||||
params.local = true
|
params.local = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,11 @@ library.add(faCircleNotch, faCog, faMinus, faArrowUp, faCirclePlus, faCheck)
|
||||||
const Timeline = {
|
const Timeline = {
|
||||||
props: {
|
props: {
|
||||||
timelineRef: Object,
|
timelineRef: Object,
|
||||||
argument: String,
|
|
||||||
embedded: Boolean,
|
|
||||||
count: Number,
|
count: Number,
|
||||||
pinnedStatusIds: Set,
|
|
||||||
inProfile: Boolean,
|
|
||||||
footerSlipgate: Object, // reference to an element where we should put our footer
|
footerSlipgate: Object, // reference to an element where we should put our footer
|
||||||
|
embedded: Boolean,
|
||||||
|
inProfile: Boolean,
|
||||||
|
skipPinned: Boolean,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -58,17 +57,8 @@ const Timeline = {
|
||||||
},
|
},
|
||||||
filteredVisibleStatuses() {
|
filteredVisibleStatuses() {
|
||||||
return [...this.timeline.visibleStatusesIds.keys()]
|
return [...this.timeline.visibleStatusesIds.keys()]
|
||||||
.filter(
|
|
||||||
(id) =>
|
|
||||||
this.timelineRef.name !== 'user' ||
|
|
||||||
(id >= this.timeline.minId && id <= this.timeline.maxId),
|
|
||||||
)
|
|
||||||
.map((id) => this.timeline.statuses.get(id))
|
.map((id) => this.timeline.statuses.get(id))
|
||||||
},
|
.filter(({ pinned }) => this.skipPinned ? !pinned : true)
|
||||||
filteredPinnedStatusIds() {
|
|
||||||
return (this.pinnedStatusIds || []).filter(
|
|
||||||
(statusId) => this.timeline.statusesObject[statusId],
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
newStatusCount() {
|
newStatusCount() {
|
||||||
return this.timeline.newStatusCount
|
return this.timeline.newStatusCount
|
||||||
|
|
@ -109,17 +99,11 @@ const Timeline = {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// id map of statuses which need to be hidden in the main list due to pinning logic
|
|
||||||
pinnedStatusIdsObject() {
|
|
||||||
return keyBy(this.pinnedStatusIds)
|
|
||||||
},
|
|
||||||
statusesToDisplay() {
|
statusesToDisplay() {
|
||||||
const amount = this.timeline.visibleStatusesIds.size
|
const amount = this.timeline.visibleStatusesIds.size
|
||||||
const statusesPerSide = Math.ceil(Math.max(3, window.innerHeight / 80))
|
const statusesPerSide = Math.ceil(Math.max(3, window.innerHeight / 80))
|
||||||
const nonPinnedIndex =
|
const min = Math.max(0, this.virtualScrollIndex - statusesPerSide)
|
||||||
this.virtualScrollIndex - this.filteredPinnedStatusIds.length
|
const max = Math.min(amount, this.virtualScrollIndex + statusesPerSide)
|
||||||
const min = Math.max(0, nonPinnedIndex - statusesPerSide)
|
|
||||||
const max = Math.min(amount, nonPinnedIndex + statusesPerSide)
|
|
||||||
return new Set(
|
return new Set(
|
||||||
[...this.timeline.visibleStatusesIds.keys()].slice(min, max),
|
[...this.timeline.visibleStatusesIds.keys()].slice(min, max),
|
||||||
)
|
)
|
||||||
|
|
@ -159,6 +143,11 @@ const Timeline = {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
timelineChange(newTimeline, oldTimeline) {
|
timelineChange(newTimeline, oldTimeline) {
|
||||||
|
// TODO this might not be necessary if we optimize mergeOrAdd
|
||||||
|
const sameName = newTimeline?.name === oldTimeline?.name
|
||||||
|
const sameArgument = newTimeline?.argument === oldTimeline?.argument
|
||||||
|
if (sameName && sameArgument) return
|
||||||
|
|
||||||
if (oldTimeline && oldTimeline.name !== 'friends') {
|
if (oldTimeline && oldTimeline.name !== 'friends') {
|
||||||
useTimelinesStore().clearTimeline(oldTimeline.name)
|
useTimelinesStore().clearTimeline(oldTimeline.name)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,17 +71,6 @@
|
||||||
class="timeline"
|
class="timeline"
|
||||||
role="feed"
|
role="feed"
|
||||||
>
|
>
|
||||||
<Conversation
|
|
||||||
v-for="statusId in filteredPinnedStatusIds"
|
|
||||||
:key="statusId + '-pinned'"
|
|
||||||
role="listitem"
|
|
||||||
class="status-fadein"
|
|
||||||
:status-id="statusId"
|
|
||||||
:pinned-status-ids-object="pinnedStatusIdsObject"
|
|
||||||
:in-profile="inProfile"
|
|
||||||
:profile-user-id="userId"
|
|
||||||
collapsable
|
|
||||||
/>
|
|
||||||
<Conversation
|
<Conversation
|
||||||
v-for="status in filteredVisibleStatuses"
|
v-for="status in filteredVisibleStatuses"
|
||||||
:key="status.id"
|
:key="status.id"
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import UserCard from 'src/components/user_card/user_card.vue'
|
||||||
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
import { useTimelinesStore } from 'src/stores/statuses.js'
|
import { useTimelinesStore } from 'src/stores/timelines.js'
|
||||||
import { useUsersStore } from 'src/stores/users.js'
|
import { useUsersStore } from 'src/stores/users.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
|
@ -38,7 +38,6 @@ const UserProfile = {
|
||||||
useInterfaceStore().setForeignProfileBackground(this.user?.background_image)
|
useInterfaceStore().setForeignProfileBackground(this.user?.background_image)
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
this.stopFetching()
|
|
||||||
useInterfaceStore().setForeignProfileBackground(null)
|
useInterfaceStore().setForeignProfileBackground(null)
|
||||||
this.$store.dispatch('clearFollowers', this.userId)
|
this.$store.dispatch('clearFollowers', this.userId)
|
||||||
this.$store.dispatch('clearFriends', this.userId)
|
this.$store.dispatch('clearFriends', this.userId)
|
||||||
|
|
@ -101,6 +100,7 @@ const UserProfile = {
|
||||||
},
|
},
|
||||||
load(userNameOrId) {
|
load(userNameOrId) {
|
||||||
const loadById = (userId) => {
|
const loadById = (userId) => {
|
||||||
|
console.log('LOAD', userId)
|
||||||
this.userId = userId
|
this.userId = userId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,10 +119,11 @@ const UserProfile = {
|
||||||
if (user) {
|
if (user) {
|
||||||
loadById(user.id)
|
loadById(user.id)
|
||||||
} else {
|
} else {
|
||||||
;(maybeId
|
const promise = maybeId
|
||||||
? this.$store.dispatch('fetchUser', maybeId)
|
? useUsersStore().fetchUser(maybeId)
|
||||||
: this.$store.dispatch('fetchUserByName', maybeName)
|
: useUsersStore().fetchUserByName(maybeName)
|
||||||
)
|
|
||||||
|
promise
|
||||||
.then(({ id }) => loadById(id))
|
.then(({ id }) => loadById(id))
|
||||||
.catch((reason) => {
|
.catch((reason) => {
|
||||||
const errorMessage = get(reason, 'error.error')
|
const errorMessage = get(reason, 'error.error')
|
||||||
|
|
@ -138,6 +139,7 @@ const UserProfile = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
switchUser(userNameOrId) {
|
switchUser(userNameOrId) {
|
||||||
|
console.log('USER SWITCH')
|
||||||
this.load(userNameOrId)
|
this.load(userNameOrId)
|
||||||
},
|
},
|
||||||
onTabSwitch(tab) {
|
onTabSwitch(tab) {
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,32 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<tab-switcher
|
<tab-switcher
|
||||||
|
v-if="userId"
|
||||||
:active-tab="tab"
|
:active-tab="tab"
|
||||||
:render-only-focused="true"
|
:render-only-focused="true"
|
||||||
:on-switch="onTabSwitch"
|
:on-switch="onTabSwitch"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
key="statuses"
|
||||||
class="statuses"
|
class="statuses"
|
||||||
:label="$t('user_card.statuses')"
|
:label="$t('user_card.statuses')"
|
||||||
:count="user.statuses_count"
|
:count="user.statuses_count"
|
||||||
:title="$t('user_profile.timeline_title')"
|
:title="$t('user_profile.timeline_title')"
|
||||||
>
|
>
|
||||||
|
<!--
|
||||||
<Timeline
|
<Timeline
|
||||||
key="statuses"
|
key="statuses"
|
||||||
:embedded="true"
|
:timeline-ref="{ name: 'userPinned', argument: userId }"
|
||||||
timeline-name="user"
|
embedded
|
||||||
:argument="userId"
|
in-profile
|
||||||
:in-profile="true"
|
:footer-slipgate="footerRef"
|
||||||
|
/>
|
||||||
|
-->
|
||||||
|
<Timeline
|
||||||
|
:timeline-ref="{ name: 'user', argument: userId }"
|
||||||
|
embedded
|
||||||
|
in-profile
|
||||||
|
skip-pinned
|
||||||
:footer-slipgate="footerRef"
|
:footer-slipgate="footerRef"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -71,24 +81,23 @@
|
||||||
<Timeline
|
<Timeline
|
||||||
key="media"
|
key="media"
|
||||||
:label="$t('user_card.media')"
|
:label="$t('user_card.media')"
|
||||||
:disabled="!media.visibleStatuses.length"
|
:disabled="!media.visibleStatusesIds.size"
|
||||||
:embedded="true"
|
|
||||||
:title="$t('user_card.media')"
|
:title="$t('user_card.media')"
|
||||||
timeline-name="media"
|
:timeline-ref="{ name: 'media', argument: userId }"
|
||||||
:argument="userId"
|
embedded
|
||||||
:in-profile="true"
|
in-profile
|
||||||
:footer-slipgate="footerRef"
|
:footer-slipgate="footerRef"
|
||||||
/>
|
/>
|
||||||
<Timeline
|
<Timeline
|
||||||
v-if="favoritesTabVisible"
|
v-if="favoritesTabVisible"
|
||||||
key="favorites"
|
key="favorites"
|
||||||
:label="$t('user_card.favorites')"
|
:label="$t('user_card.favorites')"
|
||||||
:disabled="!favorites.visibleStatuses.length"
|
:disabled="!favorites.visibleStatusesIds.size"
|
||||||
:embedded="true"
|
|
||||||
:title="$t('user_card.favorites')"
|
:title="$t('user_card.favorites')"
|
||||||
timeline-name="favorites"
|
:timeline-ref="{ name: 'favorites', argument: userId }"
|
||||||
:argument="isUs ? undefined : userId"
|
:argument="isUs ? undefined : userId"
|
||||||
:in-profile="true"
|
embedded
|
||||||
|
in-profile
|
||||||
:footer-slipgate="footerRef"
|
:footer-slipgate="footerRef"
|
||||||
/>
|
/>
|
||||||
</tab-switcher>
|
</tab-switcher>
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ const fetchAndUpdate = ({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const timelineFetcher = (timeline, argument, argumentKey, credentials) => {
|
const timelineFetcher = (timeline, argument, credentials) => {
|
||||||
const state = {
|
const state = {
|
||||||
interval: null
|
interval: null
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +113,6 @@ const timelineFetcher = (timeline, argument, argumentKey, credentials) => {
|
||||||
} = {}) => fetchAndUpdate({
|
} = {}) => fetchAndUpdate({
|
||||||
timeline,
|
timeline,
|
||||||
argument,
|
argument,
|
||||||
argumentKey,
|
|
||||||
credentials,
|
credentials,
|
||||||
}, {
|
}, {
|
||||||
maxId,
|
maxId,
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const emptyTl = (name, argument = null) => {
|
||||||
fetcher: null,
|
fetcher: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
const property = USER_TIMELINES.has(name) ? 'userId' : ARGUMENT_MAP[name]
|
const property = ARGUMENT_MAP[name]
|
||||||
|
|
||||||
if (property) {
|
if (property) {
|
||||||
result[property] = argument
|
result[property] = argument
|
||||||
|
|
@ -36,6 +36,9 @@ export const ARGUMENT_MAP = {
|
||||||
bookmarks: 'bookmarkFolderId',
|
bookmarks: 'bookmarkFolderId',
|
||||||
quotes: 'statusId',
|
quotes: 'statusId',
|
||||||
search: 'query',
|
search: 'query',
|
||||||
|
user: 'userId',
|
||||||
|
userPinned: 'userId',
|
||||||
|
media: 'userId',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultState = () => {
|
export const defaultState = () => {
|
||||||
|
|
@ -58,7 +61,6 @@ export const defaultState = () => {
|
||||||
].map((name) => [name, emptyTl(name)]))
|
].map((name) => [name, emptyTl(name)]))
|
||||||
}
|
}
|
||||||
|
|
||||||
const USER_TIMELINES = new Set(['user', 'userPinned', 'media', 'favorites'])
|
|
||||||
//const CUSTOM_SORT = new Set(['bookmarks', 'favorites'])
|
//const CUSTOM_SORT = new Set(['bookmarks', 'favorites'])
|
||||||
|
|
||||||
export const useTimelinesStore = defineStore('timelines', {
|
export const useTimelinesStore = defineStore('timelines', {
|
||||||
|
|
@ -82,7 +84,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 = USER_TIMELINES.has(name) ? 'userId' : ARGUMENT_MAP[name]
|
const property = ARGUMENT_MAP[name]
|
||||||
|
|
||||||
if (property && timeline[property] !== argument) {
|
if (property && timeline[property] !== argument) {
|
||||||
return
|
return
|
||||||
|
|
@ -148,7 +150,6 @@ export const useTimelinesStore = defineStore('timelines', {
|
||||||
timeline.fetcher = timelineFetcher(
|
timeline.fetcher = timelineFetcher(
|
||||||
timeline,
|
timeline,
|
||||||
argument,
|
argument,
|
||||||
ARGUMENT_MAP[timeline.name],
|
|
||||||
useOAuthStore().token,
|
useOAuthStore().token,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue