UI improvements
This commit is contained in:
parent
8c1d15aaae
commit
bcfe1de1b2
16 changed files with 94 additions and 40 deletions
|
|
@ -7,7 +7,7 @@
|
||||||
class="avatars-item"
|
class="avatars-item"
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
:user="user"
|
:user-id="user.id"
|
||||||
class="avatar-small"
|
class="avatar-small"
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
>
|
>
|
||||||
<div class="chat-list-item-left">
|
<div class="chat-list-item-left">
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
:user="chat.account"
|
:user-id="chat.account.id"
|
||||||
height="48px"
|
height="48px"
|
||||||
width="48px"
|
width="48px"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
v-if="author"
|
v-if="author"
|
||||||
:compact="true"
|
:compact="true"
|
||||||
:user="author"
|
:user-id="author.id"
|
||||||
/>
|
/>
|
||||||
</UserPopover>
|
</UserPopover>
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
class="titlebar-avatar"
|
class="titlebar-avatar"
|
||||||
:user="user"
|
:user-id="user.id"
|
||||||
/>
|
/>
|
||||||
</UserPopover>
|
</UserPopover>
|
||||||
<RichContent
|
<RichContent
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@ import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
import { useUsersStore } from 'src/stores/users.js'
|
import { useUsersStore } from 'src/stores/users.js'
|
||||||
|
import { useStreamingStore } from 'src/stores/streaming.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
WSConnectionStatus,
|
||||||
|
} from 'src/api/websocket.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
|
@ -20,6 +25,8 @@ import {
|
||||||
faSignOutAlt,
|
faSignOutAlt,
|
||||||
faTachometerAlt,
|
faTachometerAlt,
|
||||||
faUserPlus,
|
faUserPlus,
|
||||||
|
faPlug,
|
||||||
|
faPlugCircleXmark
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
|
|
@ -34,6 +41,8 @@ library.add(
|
||||||
faTachometerAlt,
|
faTachometerAlt,
|
||||||
faCog,
|
faCog,
|
||||||
faInfoCircle,
|
faInfoCircle,
|
||||||
|
faPlug,
|
||||||
|
faPlugCircleXmark
|
||||||
)
|
)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -93,9 +102,23 @@ export default {
|
||||||
hideSitename: (store) => store.instanceIdentity.hideSitename,
|
hideSitename: (store) => store.instanceIdentity.hideSitename,
|
||||||
}),
|
}),
|
||||||
...mapState(useUsersStore, ['currentUser']),
|
...mapState(useUsersStore, ['currentUser']),
|
||||||
|
...mapState(useStreamingStore, {
|
||||||
|
streamingConnected: (store) => store.state === WSConnectionStatus.JOINED
|
||||||
|
}),
|
||||||
|
...mapState(useMergedConfigStore, ['mergedConfig']),
|
||||||
shouldConfirmLogout() {
|
shouldConfirmLogout() {
|
||||||
return useMergedConfigStore().mergedConfig.modalOnLogout
|
return this.mergedConfig.modalOnLogout
|
||||||
},
|
},
|
||||||
|
streamingEnabled() {
|
||||||
|
return this.mergedConfig.useStreamingApi
|
||||||
|
},
|
||||||
|
streamingTooltip() {
|
||||||
|
if (this.streamingConnected) {
|
||||||
|
return this.$t('timeline.socket_reconnected')
|
||||||
|
} else {
|
||||||
|
return this.$t('timeline.socket_disconnected')
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
scrollToTop() {
|
scrollToTop() {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,25 @@
|
||||||
>
|
>
|
||||||
{{ sitename }}
|
{{ sitename }}
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<div
|
||||||
|
class="nav-icon"
|
||||||
|
v-if="streamingEnabled"
|
||||||
|
:title="streamingTooltip"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
v-if="streamingConnected"
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="plug"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FAIcon
|
||||||
|
v-else
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="plug-circle-xmark"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<router-link
|
<router-link
|
||||||
class="logo"
|
class="logo"
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
v-if="shouldShowAvatar"
|
v-if="shouldShowAvatar"
|
||||||
class="mention-avatar"
|
class="mention-avatar"
|
||||||
:user="user"
|
:user-id="user.id"
|
||||||
/><span
|
/><span
|
||||||
class="shortName"
|
class="shortName"
|
||||||
>@<span
|
>@<span
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
class="post-avatar"
|
class="post-avatar"
|
||||||
:compact="true"
|
:compact="true"
|
||||||
:user="notification.from_profile"
|
:user-id="notification.from_profile.id"
|
||||||
/>
|
/>
|
||||||
</UserPopover>
|
</UserPopover>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -223,9 +223,6 @@ const Status = {
|
||||||
botStatus() {
|
botStatus() {
|
||||||
return this.status.user.actor_type === 'Service'
|
return this.status.user.actor_type === 'Service'
|
||||||
},
|
},
|
||||||
showActorTypeIndicator() {
|
|
||||||
return !this.hideBotIndication
|
|
||||||
},
|
|
||||||
sensitiveStatus() {
|
sensitiveStatus() {
|
||||||
return this.status.nsfw
|
return this.status.nsfw
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,7 @@
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
v-if="retweet"
|
v-if="retweet"
|
||||||
class="left-side repeater-avatar"
|
class="left-side repeater-avatar"
|
||||||
:show-actor-type-indicator="showActorTypeIndicator"
|
:user-id="statusoid.user.id"
|
||||||
:user="statusoid.user"
|
|
||||||
/>
|
/>
|
||||||
<div class="right-side faint">
|
<div class="right-side faint">
|
||||||
<bdi
|
<bdi
|
||||||
|
|
@ -114,15 +113,14 @@
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
class="post-avatar"
|
class="post-avatar"
|
||||||
:show-actor-type-indicator="showActorTypeIndicator"
|
|
||||||
:compact="compact"
|
:compact="compact"
|
||||||
:user="status?.user"
|
:user-id="status?.user.id"
|
||||||
/>
|
/>
|
||||||
</UserPopover>
|
</UserPopover>
|
||||||
</a>
|
</a>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
v-else
|
v-else
|
||||||
:user="status?.user"
|
:user-id="status?.user.id"
|
||||||
class="post-avatar"
|
class="post-avatar"
|
||||||
:compact="compact"
|
:compact="compact"
|
||||||
:title="$t('status.unknown_user_info')"
|
:title="$t('status.unknown_user_info')"
|
||||||
|
|
@ -529,7 +527,6 @@
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
class="post-avatar"
|
class="post-avatar"
|
||||||
:compact="compact"
|
:compact="compact"
|
||||||
:show-actor-type-indicator="showActorTypeIndicator"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="right-side">
|
<div class="right-side">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import { useInstanceStore } from 'src/stores/instance.js'
|
import { useInstanceStore } from 'src/stores/instance.js'
|
||||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
|
import { useUsersStore } from 'src/stores/users.js'
|
||||||
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faPeopleGroup, faRobot } from '@fortawesome/free-solid-svg-icons'
|
import { faPeopleGroup, faRobot } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
@ -8,10 +10,10 @@ library.add(faRobot, faPeopleGroup)
|
||||||
|
|
||||||
const UserAvatar = {
|
const UserAvatar = {
|
||||||
props: {
|
props: {
|
||||||
// User object to show avatar of
|
// UserID of a user to show avatar of
|
||||||
user: {
|
userId: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Object,
|
type: String,
|
||||||
},
|
},
|
||||||
// Use less space and use alternative roundness
|
// Use less space and use alternative roundness
|
||||||
compact: {
|
compact: {
|
||||||
|
|
@ -19,12 +21,6 @@ const UserAvatar = {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
// Show small icon indicating if account is a bot or group
|
|
||||||
showActorTypeIndicator: {
|
|
||||||
required: false,
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
// Override avatar image URL, useful for profile editing
|
// Override avatar image URL, useful for profile editing
|
||||||
url: {
|
url: {
|
||||||
required: false,
|
required: false,
|
||||||
|
|
@ -39,7 +35,14 @@ const UserAvatar = {
|
||||||
betterShadow: useInterfaceStore().browserSupport.cssFilter,
|
betterShadow: useInterfaceStore().browserSupport.cssFilter,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {},
|
computed: {
|
||||||
|
user() {
|
||||||
|
return useUsersStore().findUser(this.userId)
|
||||||
|
},
|
||||||
|
showActorTypeIndicator() {
|
||||||
|
return useMergedConfigStore().mergedConfig.hideBotIndication
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
imgSrc(src) {
|
imgSrc(src) {
|
||||||
return !src || this.showPlaceholder ? this.defaultAvatar : src
|
return !src || this.showPlaceholder ? this.defaultAvatar : src
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
class="user-info-avatar -link"
|
class="user-info-avatar -link"
|
||||||
@click="zoomAvatar"
|
@click="zoomAvatar"
|
||||||
>
|
>
|
||||||
<UserAvatar :user="user" />
|
<UserAvatar :user-id="user.id" />
|
||||||
<div class="user-info-avatar -link -overlay">
|
<div class="user-info-avatar -link -overlay">
|
||||||
<FAIcon
|
<FAIcon
|
||||||
class="fa-scale-110 fa-old-padding"
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
@click="changeAvatar"
|
@click="changeAvatar"
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
:user="user"
|
:user-id="user.id"
|
||||||
:url="avatarImgSrc"
|
:url="avatarImgSrc"
|
||||||
/>
|
/>
|
||||||
<div class="user-info-avatar -link -overlay">
|
<div class="user-info-avatar -link -overlay">
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
v-else-if="typeof avatarAction === 'function'"
|
v-else-if="typeof avatarAction === 'function'"
|
||||||
class="user-info-avatar"
|
class="user-info-avatar"
|
||||||
:user="user"
|
:user-id="user.id"
|
||||||
@click="avatarAction"
|
@click="avatarAction"
|
||||||
/>
|
/>
|
||||||
<router-link
|
<router-link
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
class="user-info-avatar"
|
class="user-info-avatar"
|
||||||
:to="userProfileLink(user)"
|
:to="userProfileLink(user)"
|
||||||
>
|
>
|
||||||
<UserAvatar :user="user" />
|
<UserAvatar :user-id="user.id" />
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="user-summary">
|
<div class="user-summary">
|
||||||
<div class="top-line">
|
<div class="top-line">
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
class="user-list-row"
|
class="user-list-row"
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
:user="user"
|
:user-id="user.id"
|
||||||
class="avatar-small"
|
class="avatar-small"
|
||||||
:compact="true"
|
:compact="true"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1633,6 +1633,8 @@
|
||||||
"no_more_statuses": "No more statuses",
|
"no_more_statuses": "No more statuses",
|
||||||
"no_statuses": "No statuses",
|
"no_statuses": "No statuses",
|
||||||
"socket_reconnected": "Realtime connection established",
|
"socket_reconnected": "Realtime connection established",
|
||||||
|
"socket_disconnected": "Realtime connection unavaialable",
|
||||||
|
"socket_closed": "Realtime connection closed",
|
||||||
"socket_broke": "Realtime connection lost: CloseEvent code {0}",
|
"socket_broke": "Realtime connection lost: CloseEvent code {0}",
|
||||||
"quick_view_settings": "Quick view settings",
|
"quick_view_settings": "Quick view settings",
|
||||||
"quick_filter_settings": "Quick filter settings",
|
"quick_filter_settings": "Quick filter settings",
|
||||||
|
|
@ -1730,6 +1732,7 @@
|
||||||
"more_actions": "More actions on this status",
|
"more_actions": "More actions on this status",
|
||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
"load_error": "Unable to load status: {error}",
|
"load_error": "Unable to load status: {error}",
|
||||||
|
"interact_error": "Error interacting with status: {error}",
|
||||||
"admin_change_scope": "Change visibility",
|
"admin_change_scope": "Change visibility",
|
||||||
"mark_as_sensitive": "Sensitive",
|
"mark_as_sensitive": "Sensitive",
|
||||||
"mark_as_non-sensitive": "Non-sensitive"
|
"mark_as_non-sensitive": "Non-sensitive"
|
||||||
|
|
|
||||||
|
|
@ -95,14 +95,26 @@ export const useInterfaceStore = defineStore('interface', {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onStreamDisconnect(closeEvent) {
|
onStreamDisconnect(closeEvent) {
|
||||||
// TODO better explanation/localization
|
const intendedCodes = new Set([
|
||||||
const { code } = closeEvent
|
1000, // Normal (intended) closure
|
||||||
|
1001, // Going away
|
||||||
|
])
|
||||||
|
const { code } = closeEvent.original
|
||||||
|
if (intendedCodes.has(code)) {
|
||||||
|
this.pushGlobalNotice({
|
||||||
|
level: 'success',
|
||||||
|
messageKey: 'timeline.socket_closed',
|
||||||
|
messageArgs: [code],
|
||||||
|
timeout: 5000,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
this.pushGlobalNotice({
|
this.pushGlobalNotice({
|
||||||
level: 'error',
|
level: 'error',
|
||||||
messageKey: 'timeline.socket_broke',
|
messageKey: 'timeline.socket_broke',
|
||||||
messageArgs: [code],
|
messageArgs: [code],
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setTemporaryChanges({ confirm, revert }) {
|
setTemporaryChanges({ confirm, revert }) {
|
||||||
this.temporaryChangesCountdown = 10
|
this.temporaryChangesCountdown = 10
|
||||||
|
|
|
||||||
|
|
@ -338,7 +338,7 @@ export const useStatusesStore = defineStore('statuses', {
|
||||||
|
|
||||||
useInterfaceStore().pushGlobalNotice({
|
useInterfaceStore().pushGlobalNotice({
|
||||||
level: 'error',
|
level: 'error',
|
||||||
messageKey: 'status.react_error',
|
messageKey: 'status.interact_error',
|
||||||
messageArgs: [error],
|
messageArgs: [error],
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue