Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85648578
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
34 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js
index ab87d8b8a0..1af3e6e4cd 100644
--- a/src/components/account_actions/account_actions.js
+++ b/src/components/account_actions/account_actions.js
@@ -1,112 +1,112 @@
import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import Popover from 'src/components/popover/popover.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue'
import UserListMenu from 'src/components/user_list_menu/user_list_menu.vue'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useReportsStore } from 'src/stores/reports'
import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faEllipsisV } from '@fortawesome/free-solid-svg-icons'
library.add(faEllipsisV)
const AccountActions = {
props: ['user', 'relationship'],
data() {
return {
showingConfirmBlock: false,
showingConfirmRemoveFollower: false,
}
},
components: {
ProgressButton,
Popover,
UserListMenu,
ConfirmModal: defineAsyncComponent(
() => import('src/components/confirm_modal/confirm_modal.vue'),
),
UserTimedFilterModal: defineAsyncComponent(
() =>
import(
'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
),
),
},
methods: {
showConfirmRemoveUserFromFollowers() {
this.showingConfirmRemoveFollower = true
},
hideConfirmRemoveUserFromFollowers() {
this.showingConfirmRemoveFollower = false
},
hideConfirmBlock() {
this.showingConfirmBlock = false
},
showRepeats() {
- this.$store.dispatch('showReblogs', this.user.id)
+ useUsersStore().showReblogs(this.user.id)
},
hideRepeats() {
- this.$store.dispatch('hideReblogs', this.user.id)
+ useUsersStore().hideReblogs(this.user.id)
},
blockUser() {
if (this.$refs.timedBlockDialog) {
this.$refs.timedBlockDialog.optionallyPrompt()
} else {
if (!this.shouldConfirmBlock) {
this.doBlockUser()
} else {
this.showingConfirmBlock = true
}
}
},
doBlockUser() {
- this.$store.dispatch('blockUser', { id: this.user.id })
+ useUsersStore().blockUser(this.user.id)
this.hideConfirmBlock()
},
unblockUser() {
- this.$store.dispatch('unblockUser', this.user.id)
+ useUsersStore().unblockUser(this.user.id)
},
removeUserFromFollowers() {
if (!this.shouldConfirmRemoveUserFromFollowers) {
this.doRemoveUserFromFollowers()
} else {
this.showConfirmRemoveUserFromFollowers()
}
},
doRemoveUserFromFollowers() {
- this.$store.dispatch('removeUserFromFollowers', this.user.id)
+ useUsersStore().removeUserFromFollowers(this.user.id)
this.hideConfirmRemoveUserFromFollowers()
},
reportUser() {
useReportsStore().openUserReportingModal({ userId: this.user.id })
},
openChat() {
this.$router.push({
name: 'chat',
params: {
username: useUsersStore().currentUser.screen_name,
recipient_id: this.user.id,
},
})
},
},
computed: {
shouldConfirmBlock() {
return useMergedConfigStore().mergedConfig.modalOnBlock
},
shouldConfirmRemoveUserFromFollowers() {
return useMergedConfigStore().mergedConfig.modalOnRemoveUserFromFollowers
},
...mapState(useInstanceCapabilitiesStore, [
'blockExpiration',
'pleromaChatMessagesAvailable',
]),
},
}
export default AccountActions
diff --git a/src/components/block_card/block_card.js b/src/components/block_card/block_card.js
index 11120574b4..2ee5785206 100644
--- a/src/components/block_card/block_card.js
+++ b/src/components/block_card/block_card.js
@@ -1,51 +1,51 @@
import { mapState } from 'pinia'
import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useUsersStore } from 'src/stores/users.js'
const BlockCard = {
props: ['userId'],
computed: {
user() {
return useUsersStore().findUser(this.userId)
},
relationship() {
return useUsersStore().relationship(this.userId)
},
blocked() {
return this.relationship.blocking
},
blockExpiryAvailable() {
return Object.hasOwn(this.user, 'block_expires_at')
},
blockExpiry() {
return this.user.block_expires_at === false
? this.$t('user_card.block_expires_forever')
: this.$t('user_card.block_expires_at', [
new Date(this.user.mute_expires_at).toLocaleString(),
])
},
...mapState(useInstanceCapabilitiesStore, ['blockExpiration']),
},
components: {
BasicUserCard,
UserTimedFilterModal,
},
methods: {
unblockUser() {
- this.$store.dispatch('unblockUser', this.user.id)
+ useUsersStore().unblockUser(this.user.id)
},
blockUser() {
if (this.blockExpiration) {
this.$refs.timedBlockDialog.optionallyPrompt()
} else {
- this.$store.dispatch('blockUser', { id: this.user.id })
+ useUsersStore().blockUser(this.user.id)
}
},
},
}
export default BlockCard
diff --git a/src/components/confirm_modal/mute_confirm.js b/src/components/confirm_modal/mute_confirm.js
index 862405a8e6..2247c2e912 100644
--- a/src/components/confirm_modal/mute_confirm.js
+++ b/src/components/confirm_modal/mute_confirm.js
@@ -1,91 +1,92 @@
import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import Select from 'src/components/select/select.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
+import { useStatusesStore } from 'src/stores/statuses.js'
import { useUsersStore } from 'src/stores/users.js'
export default {
props: ['type', 'user', 'status'],
emits: ['hide', 'show', 'muted'],
data: () => ({
showing: false,
}),
components: {
ConfirmModal: defineAsyncComponent(
() => import('src/components/confirm_modal/confirm_modal.vue'),
),
Select,
},
computed: {
domain() {
return this.user.fqn.split('@')[1]
},
keypath() {
if (this.type === 'domain') {
return 'user_card.mute_domain_confirm'
} else if (this.type === 'conversation') {
return 'user_card.mute_conversation_confirm'
}
},
conversationIsMuted() {
return this.status.conversation_muted
},
domainIsMuted() {
return new Set(useUsersStore().currentUser.domainMutes).has(this.domain)
},
shouldConfirm() {
switch (this.type) {
case 'domain': {
return this.mergedConfig.modalOnMuteDomain
}
default: {
// conversation
return this.mergedConfig.modalOnMuteConversation
}
}
},
...mapState(useMergedConfigStore, ['mergedConfig']),
},
methods: {
optionallyPrompt() {
if (this.shouldConfirm) {
this.show()
} else {
this.doMute()
}
},
show() {
this.showing = true
this.$emit('show')
},
hide() {
this.showing = false
this.$emit('hide')
},
doMute() {
switch (this.type) {
case 'domain': {
if (!this.domainIsMuted) {
- this.$store.dispatch('muteDomain', this.domain)
+ useUsersStore().muteDomain(this.domain)
} else {
- this.$store.dispatch('unmuteDomain', this.domain)
+ useUsersStore().unmuteDomain(this.domain)
}
break
}
case 'conversation': {
if (!this.conversationIsMuted) {
- this.$store.dispatch('muteConversation', { id: this.status.id })
+ useStatusesStore().muteConversation(this.status.id)
} else {
- this.$store.dispatch('unmuteConversation', { id: this.status.id })
+ useStatusesStore().unmuteConversation(this.status.id)
}
break
}
}
this.$emit('muted')
this.hide()
},
},
}
diff --git a/src/components/status_action_buttons/action_button_container.js b/src/components/status_action_buttons/action_button_container.js
index 3c371ac74e..cdb83c0b5e 100644
--- a/src/components/status_action_buttons/action_button_container.js
+++ b/src/components/status_action_buttons/action_button_container.js
@@ -1,150 +1,151 @@
import { defineAsyncComponent } from 'vue'
import Popover from 'src/components/popover/popover.vue'
import ActionButton from './action_button.vue'
import { useAdminSettingsStore } from 'src/stores/admin_settings.js'
+import { useStatusesStore } from 'src/stores/statuses.js'
import { useUsersStore } from 'src/stores/users.js'
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faEnvelope,
faEye,
faEyeSlash,
faFolderTree,
faGlobe,
faLock,
faLockOpen,
faUser,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faUser,
faGlobe,
faFolderTree,
faEye,
faEyeSlash,
faLock,
faLockOpen,
faEnvelope,
)
export default {
components: {
ActionButton,
Popover,
MuteConfirm: defineAsyncComponent(
() => import('src/components/confirm_modal/mute_confirm.vue'),
),
UserTimedFilterModal: defineAsyncComponent(
() =>
import(
'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
),
),
},
props: ['button', 'status', 'defaultButton', 'hideLabel'],
emits: ['emojiPickerShown'],
mounted() {
if (this.button.name === 'mute') {
this.$store.dispatch('fetchDomainMutes')
}
},
data() {
return {
randomSeed: genRandomSeed(),
}
},
computed: {
buttonClass() {
return [
this.button.name + '-button',
{
'-with-extra': this.button.name === 'bookmark',
'-extra': this.extra,
'-quick': !this.extra,
},
]
},
user() {
return this.status.user
},
userIsMuted() {
return useUsersStore().relationship(this.user.id).muting
},
conversationIsMuted() {
return this.status.thread_muted
},
domain() {
return this.user.fqn.split('@')[1]
},
domainIsMuted() {
return new Set(useUsersStore().currentUser.domainMutes).has(this.domain)
},
availableScopes() {
return ['private', 'unlisted', 'direct', 'public'].filter((scope) => {
return scope !== this.status.visibility
})
},
},
methods: {
visibilityIcon(visibility) {
switch (visibility) {
case 'private':
return 'lock'
case 'unlisted':
return 'lock-open'
case 'direct':
return 'envelope'
case 'local':
return 'igloo'
default:
return 'globe'
}
},
unmuteUser() {
- return this.$store.dispatch('unmuteUser', this.user.id)
+ return useUsersStore().unmuteUser(this.user.id)
},
unmuteConversation() {
- return this.$store.dispatch('unmuteConversation', { id: this.status.id })
+ return useStatusesStore().unmuteConversation(this.status.id)
},
unmuteDomain() {
- return this.$store.dispatch('unmuteDomain', this.domain)
+ return useUsersStore().unmuteDomain(this.domain)
},
toggleUserMute() {
if (this.userIsMuted) {
this.unmuteUser()
} else {
this.$refs.confirmUser.optionallyPrompt()
}
},
setScope(visibility) {
return useAdminSettingsStore().changeStatusScope({
id: this.status.id,
visibility,
})
},
setSensitive(sensitive) {
useAdminSettingsStore().changeStatusScope({
id: this.status.id,
sensitive,
})
},
toggleConversationMute() {
if (this.conversationIsMuted) {
this.unmuteConversation()
} else {
this.$refs.confirmConversation.optionallyPrompt()
}
},
toggleDomainMute() {
if (this.domainIsMuted) {
this.unmuteDomain()
} else {
this.$refs.confirmDomain.optionallyPrompt()
}
},
},
}
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index f4b1123e27..5304608b81 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -1,623 +1,623 @@
import {
isEqual,
escape as ldEscape,
unescape as ldUnescape,
merge,
} from 'lodash'
import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import ColorInput from 'src/components/color_input/color_input.vue'
import EmojiInput from 'src/components/emoji_input/emoji_input.vue'
import suggestor from 'src/components/emoji_input/suggestor.js'
import FollowButton from 'src/components/follow_button/follow_button.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue'
import Select from 'src/components/select/select.vue'
import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import UserLink from 'src/components/user_link/user_link.vue'
import { useEmojiStore } from 'src/stores/emoji.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface'
import { useMediaViewerStore } from 'src/stores/media_viewer'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { usePostStatusStore } from 'src/stores/post_status'
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import { useUsersStore } from 'src/stores/users.js'
import { updateProfile } from 'src/api/user.js'
import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js'
import localeService from 'src/services/locale/locale.service.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBell,
faBirthdayCake,
faClockRotateLeft,
faEdit,
faExpandAlt,
faExternalLinkAlt,
faRss,
faSave,
faSearchPlus,
faTimes,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faSave,
faRss,
faBell,
faSearchPlus,
faExternalLinkAlt,
faEdit,
faTimes,
faExpandAlt,
faBirthdayCake,
faClockRotateLeft,
)
const KNOWN_TAGS = new Set([
'mrf_tag:media-force-nsfw',
'mrf_tag:media-strip',
'mrf_tag:force-unlisted',
'mrf_tag:sandbox',
'mrf_tag:disable-remote-subscription',
'mrf_tag:disable-any-subscription',
])
export default {
props: {
// Enables all the options for profile editing, used in settings -> profile tab
editable: {
required: false,
default: false,
type: Boolean,
},
// ID of user to show data of
userId: {
required: true,
type: String,
},
// Use a compact layout that hides bio, stats etc.
hideBio: {
required: false,
default: false,
type: Boolean,
},
// Hide action buttons
hideButtons: {
required: false,
default: false,
type: Boolean,
},
// default - open profile, 'zoom' - zoom, function - call function
avatarAction: {
required: false,
type: String,
default: 'default',
},
// Show note editor if supported
hasNoteEditor: {
required: false,
type: Boolean,
default: false,
},
// Show close icon (for popovers)
showClose: {
required: false,
type: Boolean,
default: false,
},
// Show close icon (for popovers)
showExpand: {
required: false,
type: Boolean,
default: false,
},
// Disable forced 3:1 aspect ratio
compact: {
required: false,
type: Boolean,
default: false,
},
},
components: {
DialogModal: defineAsyncComponent(
() => import('src/components/dialog_modal/dialog_modal.vue'),
),
UserAvatar,
Checkbox,
RemoteFollow: defineAsyncComponent(
() => import('src/components/remote_follow/remote_follow.vue'),
),
ModerationTools: defineAsyncComponent(
() => import('src/components/moderation_tools/moderation_tools.vue'),
),
AccountActions: defineAsyncComponent(
() => import('src/components/account_actions/account_actions.vue'),
),
ProgressButton,
FollowButton,
Select,
UserLink,
UserNote: defineAsyncComponent(
() => import('src/components/user_note/user_note.vue'),
),
UserTimedFilterModal: defineAsyncComponent(
() =>
import(
'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
),
),
ColorInput,
EmojiInput,
ImageCropper: defineAsyncComponent(
() => import('src/components/image_cropper/image_cropper.vue'),
),
},
data() {
const user = useUsersStore().findUser(this.userId)
return {
followRequestInProgress: false,
// Editable stuff
editImage: false,
newName: user.name_unescaped,
editingName: false,
newBio: ldUnescape(user.description),
editingBio: false,
newAvatar: null,
newAvatarFile: null,
newBanner: null,
newBannerFile: null,
newActorType: user.actor_type,
newBirthday: user.birthday,
newShowBirthday: user.show_birthday,
newShowRole: user.show_role,
newFields: user.fields?.map((field) => ({
name: field.name,
value: field.value,
})),
editingFields: false,
}
},
created() {
useUsersStore().fetchUserRelationship(this.user.id)
},
computed: {
escapedNewBio() {
return ldEscape(this.newBio).replaceAll('\n', '<br>')
},
somethingToSave() {
if (this.newName !== this.user.name_unescaped) return true
if (this.newBio !== ldUnescape(this.user.description)) return true
if (this.newAvatar !== null) return true
if (this.newBanner !== null) return true
if (this.newActorType !== this.user.actor_type) return true
if (this.newBirthday !== this.user.birthday) return true
if (this.newShowBirthday !== this.user.show_birthday) return true
if (this.newShowRole !== this.user.show_role) return true
if (
!isEqual(
this.newFields,
this.user.fields?.map((field) => ({
name: field.name,
value: field.value,
})),
)
)
return true
return false
},
groupActorAvailable() {
return useInstanceCapabilitiesStore().groupActorAvailable
},
availableActorTypes() {
return this.groupActorAvailable
? ['Person', 'Service', 'Group']
: ['Person', 'Service']
},
user() {
return useUsersStore().findUser(this.userId)
},
role() {
return this.user.role
},
relationship() {
return useUsersStore().relationship(this.userId)
},
isOtherUser() {
return this.user.id !== useUsersStore().currentUser.id
},
subscribeUrl() {
const serverUrl = new URL(this.user.statusnet_profile_url)
return `${serverUrl.protocol}//${serverUrl.host}/main/ostatus`
},
loggedIn() {
return useUsersStore().currentUser
},
dailyAvg() {
const days = Math.ceil(
(new Date() - new Date(this.user.created_at)) / (60 * 60 * 24 * 1000),
)
return Math.round(this.user.statuses_count / days)
},
emoji() {
return useEmojiStore().customEmoji.map((e) => ({
shortcode: e.displayText,
static_url: e.imageUrl,
url: e.imageUrl,
}))
},
userHighlightType: {
get() {
return useUserHighlightStore().get(this.user.screen_name).type
},
set(type) {
if (type !== 'disabled') {
useUserHighlightStore().setAndSave({
user: this.user.screen_name,
value: { type },
})
} else {
useUserHighlightStore().unsetAndSave({ user: this.user.screen_name })
}
},
},
userHighlightColor: {
get() {
return useUserHighlightStore().get(this.user.screen_name).color
},
set(color) {
useUserHighlightStore().setAndSave({
user: this.user.screen_name,
value: { color },
})
},
},
visibleRole() {
if (!this.user.show_role && !this.user.adminData) {
return
}
const rights = this.user.rights
if (!rights) {
return
}
const validRole = rights.admin || rights.moderator
const roleTitle = rights.admin ? 'admin' : 'moderator'
return validRole && roleTitle
},
hideFollowsCount() {
return this.isOtherUser && this.user.hide_follows_count
},
hideFollowersCount() {
return this.isOtherUser && this.user.hide_followers_count
},
showModerationMenu() {
const privileges = this.loggedIn.privileges
return (
this.loggedIn.role === 'admin' ||
privileges.has('users_manage_activation_state') ||
privileges.has('users_delete') ||
privileges.has('users_manage_tags')
)
},
hasNote() {
return this.relationship.note
},
supportsNote() {
return 'note' in this.relationship
},
muteExpiryAvailable() {
return Object.hasOwn(this.user, 'mute_expires_at')
},
muteExpiry() {
return this.user.mute_expires_at === false
? this.$t('user_card.mute_expires_forever')
: this.$t('user_card.mute_expires_at', [
new Date(this.user.mute_expires_at).toLocaleString(),
])
},
blockExpiryAvailable() {
return Object.hasOwn(this.user, 'block_expires_at')
},
blockExpiry() {
return this.user.block_expires_at == null
? this.$t('user_card.block_expires_forever')
: this.$t('user_card.block_expires_at', [
new Date(this.user.mute_expires_at).toLocaleString(),
])
},
formattedBirthday() {
const browserLocale = localeService.internalToBrowserLocale(
this.$i18n.locale,
)
return (
this.user.birthday &&
new Date(Date.parse(this.user.birthday)).toLocaleDateString(
browserLocale,
{ timeZone: 'UTC', day: 'numeric', month: 'long', year: 'numeric' },
)
)
},
formattedJoinDate() {
const browserLocale = localeService.internalToBrowserLocale(
this.$i18n.locale,
)
return (
this.user.created_at &&
new Date(Date.parse(this.user.created_at)).toLocaleDateString(
browserLocale,
{ timeZone: 'UTC', day: 'numeric', month: 'long', year: 'numeric' },
)
)
},
// Editable stuff
avatarImgSrc() {
const currentUrl =
this.user.profile_image_url_original || this.defaultAvatar
if (!this.editable) return currentUrl
const newUrl =
this.newAvatar === null ? this.defaultAvatar : this.newAvatar
return this.newAvatar === null ? currentUrl : newUrl
},
bannerImgSrc() {
const currentUrl = this.user.cover_photo || this.defaultBanner
if (!this.editable) return currentUrl
const newUrl =
this.newBanner === null ? this.defaultBanner : this.newBanner
return this.newBanner === null ? currentUrl : newUrl
},
defaultAvatar() {
return (
useInstanceStore().server +
useInstanceStore().instanceIdentity.defaultAvatar
)
},
defaultBanner() {
return (
useInstanceStore().server +
useInstanceStore().instanceIdentity.defaultBanner
)
},
isDefaultAvatar() {
const baseAvatar = useInstanceStore().instanceIdenitity.defaultAvatar
return (
!useUsersStore().currentUser.profile_image_url ||
useUsersStore().currentUser.profile_image_url.includes(baseAvatar)
)
},
isDefaultBanner() {
const baseBanner = useInstanceStore().instanceIdentity.defaultBanner
return (
!useUsersStore().currentUser.cover_photo ||
useUsersStore().currentUser.cover_photo.includes(baseBanner)
)
},
fieldsLimits() {
return useInstanceStore().limits.fieldsLimits
},
maxFields() {
return this.fieldsLimits ? this.fieldsLimits.maxFields : 0
},
emojiUserSuggestor() {
return suggestor({
emoji: [
...useEmojiStore().standardEmojiList,
...useEmojiStore().customEmoji,
],
store: this.$store,
})
},
emojiSuggestor() {
return suggestor({
emoji: [
...useEmojiStore().standardEmojiList,
...useEmojiStore().customEmoji,
],
})
},
allowNonSquareEmoji() {
return this.mergedConfig.nonSquareEmoji
},
pauseMfm() {
return this.mergedConfig.pauseMfm
},
scaleMfm() {
return this.mergedConfig.scaleMfm
},
hideUserStats() {
return this.mergedConfig.hideUserStats
},
hideRemarks() {
return this.mergedConfig.userCardHidePersonalMarks
},
...mapState(useMergedConfigStore, ['mergedConfig']),
},
methods: {
isKnownTag(tag) {
return KNOWN_TAGS.has(tag)
},
muteUser() {
this.$refs.timedMuteDialog.optionallyPrompt()
},
unmuteUser() {
- this.$store.dispatch('unmuteUser', this.user.id)
+ return useUsersStore().unmuteUser(this.user.id)
},
subscribeUser() {
- return this.$store.dispatch('subscribeUser', this.user.id)
+ return useUsersStore().subscribeUser(this.user.id)
},
unsubscribeUser() {
- return this.$store.dispatch('unsubscribeUser', this.user.id)
+ return useUsersStore().unsubscribeUser(this.user.id)
},
linkClicked({ target }) {
if (target.tagName === 'SPAN') {
target = target.parentNode
}
if (target.tagName === 'A') {
window.open(target.href, '_blank')
}
},
userProfileLink(user) {
return generateProfileLink(
user.id,
user.screen_name,
useInstanceStore().restrictedNicknames,
)
},
openProfileTab() {
useInterfaceStore().openSettingsModalTab('profile')
},
zoomAvatar() {
const attachment = {
url: this.user.profile_image_url_original,
type: 'image',
}
useMediaViewerStore().setMedia([attachment])
useMediaViewerStore().setCurrentMedia(attachment)
},
mentionUser() {
usePostStatusStore().openPostStatusModal({
profileMention: this.user,
})
},
onAvatarClickHandler(e) {
if (this.onAvatarClick) {
e.preventDefault()
this.onAvatarClick()
}
},
// Editable stuff
changeAvatar() {
this.editImage = 'avatar'
},
changeBanner() {
this.editImage = 'banner'
},
submitImage({ canvas, file }) {
if (canvas) {
return canvas.toBlob((data) =>
this.submitImage({ canvas: null, file: data }),
)
}
const reader = new window.FileReader()
reader.onload = (e) => {
const dataUrl = e.target.result
if (this.editImage === 'avatar') {
this.newAvatar = dataUrl
this.newAvatarFile = file
} else {
this.newBanner = dataUrl
this.newBannerFile = file
}
this.editImage = false
}
reader.readAsDataURL(file)
},
resetImage() {
if (this.editImage === 'avatar') {
this.newAvatar = null
this.newAvatarFile = null
} else {
this.newBanner = null
this.newBannerFile = null
}
this.editImage = false
},
addField() {
if (this.newFields.length < this.maxFields) {
this.newFields.push({ name: '', value: '' })
}
},
deleteField(index) {
this.newFields.splice(index, 1)
},
propsToNative(props) {
return propsToNative(props)
},
cancelImageText() {
return
},
resetState() {
const user = useUsersStore().currentUser
this.newName = user.name_unescaped
this.newBio = ldUnescape(user.description)
this.newAvatar = null
this.newAvatarFile = null
this.newBanner = null
this.newBannerFile = null
this.newActorType = user.actor_type
this.newBirthday = user.birthday
this.newShowBirthday = user.show_birthday
this.newShowRole = user.show_role
this.newFields = user.fields.map((field) => ({
name: field.name,
value: field.value,
}))
},
updateProfile() {
const params = {
note: this.newBio,
// Backend notation.
display_name: this.newName,
fields_attributes: this.newFields.filter((el) => el != null),
show_role: !!this.newShowRole,
birthday: this.newBirthday || '',
show_birthday: !!this.newShowBirthday,
}
if (this.newActorType) {
params.actor_type = this.newActorType
}
if (this.newAvatarFile !== null) {
params.avatar = this.newAvatarFile
}
if (this.newBannerFile !== null) {
params.header = this.newBannerFile
}
updateProfile({ params })
.then(({ data: user, ...rest }) => {
this.newFields.splice(this.newFields.length)
merge(this.newFields, user.fields)
useUsersStore().addNewUsers({ data: user, ...rest })
this.resetState()
})
.catch((error) => {
this.displayUploadError(error)
})
},
displayUploadError(error) {
useInterfaceStore().pushGlobalNotice({
messageKey: 'upload.error.message',
messageArgs: [error.message],
level: 'error',
})
},
},
}
diff --git a/src/components/user_timed_filter_modal/user_timed_filter_modal.js b/src/components/user_timed_filter_modal/user_timed_filter_modal.js
index f0c1509991..360c73ee8f 100644
--- a/src/components/user_timed_filter_modal/user_timed_filter_modal.js
+++ b/src/components/user_timed_filter_modal/user_timed_filter_modal.js
@@ -1,116 +1,116 @@
import { defineAsyncComponent } from 'vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import Select from 'src/components/select/select.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
+import { useUsersStore } from 'src/stores/users.js'
import { durationStrToMs } from 'src/services/date_utils/date_utils.js'
const UserTimedFilterModal = {
data() {
const action = this.isMute
? useMergedConfigStore().mergedConfig.onMuteDefaultAction
: useMergedConfigStore().mergedConfig.onBlockDefaultAction
const doAsk = action === 'ask'
const defaultValues = {}
if (doAsk || action === 'forever') {
defaultValues.expiration = 14
defaultValues.expirationUnit = 'd'
if (action === 'forever') {
defaultValues.forever = true
}
} else {
const unit = action.replace(/[0-9,.]+/, '')
const value = action.replace(/[^0-9,.]+/, '')
defaultValues.expiration = value
defaultValues.expirationUnit = unit
}
return {
showing: false,
forever: false,
dontAskAgain: false,
...defaultValues,
}
},
components: {
ConfirmModal: defineAsyncComponent(
() => import('src/components/confirm_modal/confirm_modal.vue'),
),
Select,
Checkbox,
},
props: {
isMute: Boolean,
user: Object,
},
computed: {
shouldConfirm() {
if (this.isMute) {
return useMergedConfigStore().mergedConfig.onMuteDefaultAction === 'ask'
} else {
return (
useMergedConfigStore().mergedConfig.onBlockDefaultAction === 'ask'
)
}
},
expiryString() {
return this.expiration.toString() + this.expirationUnit
},
expirySeconds() {
return Math.floor(durationStrToMs(this.expiryString) / 1000)
},
- requestBody() {
- const object = { id: this.user.id }
- if (!this.forever) {
- object.expiresIn = this.expirySeconds
- }
- return object
- },
},
watch: {
expiration(newVal) {
if (newVal <= 0) {
this.expiration = 1
}
},
},
methods: {
optionallyPrompt() {
if (this.shouldConfirm) {
this.showing = true
} else {
this.accept()
}
},
accept() {
if (this.isMute) {
- this.$store.dispatch('muteUser', this.requestBody)
+ useUsersStore().muteUser(
+ this.user.id,
+ this.forever ? undefined : this.expirySeconds,
+ )
if (this.dontAskAgain) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'onMuteDefaultAction',
value: this.expiryString,
})
}
} else {
- this.$store.dispatch('blockUser', this.requestBody)
+ useUsersStore().blockUser(
+ this.user.id,
+ this.forever ? undefined : this.expirySeconds,
+ )
if (this.dontAskAgain) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'onBlockDefaultAction',
value: this.expiryString,
})
}
}
this.showing = false
},
cancel() {
this.showing = false
},
},
}
export default UserTimedFilterModal
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Aug 28, 3:20 PM (14 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1736478
Default Alt Text
(34 KB)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline
Log In to Comment