forked from AkkomaGang/akkoma-fe
Compare commits
94 commits
disqordia
...
disqordia-
Author | SHA1 | Date | |
---|---|---|---|
|
78e9fff730 | ||
|
6d430d53d8 | ||
e853b56eb9 | |||
a84c7a8152 | |||
8c70bb4301 | |||
d01e1e16b0 | |||
dd1a949590 | |||
6774b0d468 | |||
7f09a45b99 | |||
d60c629a86 | |||
22ceb1772a | |||
ba9634ee41 | |||
2b6d3ff42b | |||
|
edd42664ca | ||
|
b7a2b111c3 | ||
a6051f49cf | |||
5be3326f22 | |||
|
fb55bb2113 | ||
a6d8550c83 | |||
35d32524b0 | |||
0e86f707ff | |||
bb6ee79e3e | |||
cffcdd04bd | |||
c23964b7a8 | |||
6e31816c7d | |||
e39e7d5395 | |||
fa80d2627d | |||
5c9c92669c | |||
7a60b3a455 | |||
311b38f9fb | |||
a98d63fa00 | |||
acdb03f494 | |||
296ea3c993 | |||
dd42d8e92c | |||
|
e69dddee69 | ||
5abce529ca | |||
30a5c092b2 | |||
69fb3c9a87 | |||
ca0e15f7a8 | |||
6bf8513433 | |||
20c4cbfd92 | |||
b2b5c81e25 | |||
2a34a63c01 | |||
738f8a3b9a | |||
783c198125 | |||
0b0e49606a | |||
7751d9b62b | |||
6ff06ceaf5 | |||
c876b54bee | |||
98ba191c28 | |||
aa4fd497a3 | |||
1f5ae0543c | |||
f57f1b7c7a | |||
a06be20eac | |||
60f9da14dc | |||
fd8a2413ca | |||
|
5d8cba4ca2 | ||
c4f5c5aac2 | |||
d0dbe0c921 | |||
1800cb94e8 | |||
f57e977c41 | |||
2dc954ebfa | |||
24bded2509 | |||
42a13c0822 | |||
897728189e | |||
e8160c8403 | |||
f9ac714caa | |||
|
acdfa056d1 | ||
|
5b95f182c5 | ||
|
c29080a141 | ||
|
a57f8d026d | ||
|
097823d790 | ||
5135720adc | |||
54192564b9 | |||
bebd5575b6 | |||
cd72d1370c | |||
baaec9d14b | |||
f5e29ff52e | |||
f3de693f0e | |||
26033e62b8 | |||
57aa0d8da8 | |||
b792655f7a | |||
945d4f633e | |||
1964193000 | |||
64f8d854c8 | |||
18f817d73d | |||
7eed382ea9 | |||
2b945a2c0c | |||
b93a3c8ab0 | |||
488cd43080 | |||
6b2322d81c | |||
f803393219 | |||
68ef914e15 | |||
6711b197ef |
108 changed files with 2525 additions and 541 deletions
|
@ -10,3 +10,5 @@ Contributors of this project.
|
||||||
- shpuld (shpuld@shitposter.club): CSS and styling
|
- shpuld (shpuld@shitposter.club): CSS and styling
|
||||||
- Vincent Guth (https://unsplash.com/photos/XrwVIFy6rTw): Background images.
|
- Vincent Guth (https://unsplash.com/photos/XrwVIFy6rTw): Background images.
|
||||||
- hj (hj@shigusegubu.club): Code
|
- hj (hj@shigusegubu.club): Code
|
||||||
|
- Sean King (seanking@freespeechextremist.com): Code
|
||||||
|
- Tusooa Zhu (tusooa@kazv.moe): Code
|
||||||
|
|
|
@ -6,7 +6,11 @@ This is a fork of Pleroma-FE from the Pleroma project, with support for new Akko
|
||||||
|
|
||||||
# For Translators
|
# For Translators
|
||||||
|
|
||||||
To translate Pleroma-FE, add your language to [src/i18n/messages.js](https://akkoma.dev/AkkomaGang/pleroma-fe/src/branch/develop/src/i18n/messages.js). Pleroma-FE will set your language by your browser locale, but you can temporarily force it in the code by changing the locale in main.js.
|
The [Weblate UI](https://translate.akkoma.dev/projects/akkoma/pleroma-fe/) is recommended for adding or modifying translations for Pleroma-FE.
|
||||||
|
|
||||||
|
Alternatively, edit/create `src/i18n/$LANGUAGE_CODE.json` (where `$LANGUAGE_CODE` is the [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for your language), then add your language to [src/i18n/messages.js](https://akkoma.dev/AkkomaGang/pleroma-fe/src/branch/develop/src/i18n/messages.js) if it doesn't already exist there.
|
||||||
|
|
||||||
|
Pleroma-FE will set your language by your browser locale, but you can temporarily force it in the code by changing the locale in main.js.
|
||||||
|
|
||||||
# FOR ADMINS
|
# FOR ADMINS
|
||||||
|
|
||||||
|
|
10
index.html
10
index.html
|
@ -10,11 +10,21 @@
|
||||||
<link rel="stylesheet" href="/static/font/css/lato.css">
|
<link rel="stylesheet" href="/static/font/css/lato.css">
|
||||||
<link rel="stylesheet" href="/static/mfm.css">
|
<link rel="stylesheet" href="/static/mfm.css">
|
||||||
<!--server-generated-meta-->
|
<!--server-generated-meta-->
|
||||||
|
<link rel="manifest" href="/static/manifest.json" />
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar" content="black-translucent" />
|
||||||
|
<link rel="apple-touch-icon" href="/images/icons/icon-512x512.png"/>
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
|
<meta name="theme-color" content="#000000" />
|
||||||
|
<meta name="theme-color-orig" content="#000000" />
|
||||||
<link rel="icon" type="image/png" href="/favicon.png">
|
<link rel="icon" type="image/png" href="/favicon.png">
|
||||||
</head>
|
</head>
|
||||||
<body class="hidden">
|
<body class="hidden">
|
||||||
<noscript>To use Pleroma, please enable JavaScript.</noscript>
|
<noscript>To use Pleroma, please enable JavaScript.</noscript>
|
||||||
|
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/static/service-worker.js');} else {console.log("Service worker is not supported");}</script>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
<div id="modal"></div>
|
||||||
<!-- built files will be auto injected -->
|
<!-- built files will be auto injected -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -10,7 +10,9 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil
|
||||||
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
||||||
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
|
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
|
||||||
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
||||||
|
import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
|
||||||
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
||||||
|
import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue'
|
||||||
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
|
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
|
||||||
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
|
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
@ -33,6 +35,8 @@ export default {
|
||||||
SettingsModal,
|
SettingsModal,
|
||||||
UserReportingModal,
|
UserReportingModal,
|
||||||
PostStatusModal,
|
PostStatusModal,
|
||||||
|
EditStatusModal,
|
||||||
|
StatusHistoryModal,
|
||||||
GlobalNoticeList
|
GlobalNoticeList
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
@ -83,6 +87,7 @@ export default {
|
||||||
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || this.layoutType === 'mobile'
|
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || this.layoutType === 'mobile'
|
||||||
},
|
},
|
||||||
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
|
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
|
||||||
|
editingAvailable () { return this.$store.state.instance.editingAvailable },
|
||||||
layoutType () { return this.$store.state.interface.layoutType },
|
layoutType () { return this.$store.state.interface.layoutType },
|
||||||
privateMode () { return this.$store.state.instance.private },
|
privateMode () { return this.$store.state.instance.private },
|
||||||
reverseLayout () {
|
reverseLayout () {
|
||||||
|
|
|
@ -58,8 +58,10 @@
|
||||||
<MobilePostStatusButton />
|
<MobilePostStatusButton />
|
||||||
<UserReportingModal />
|
<UserReportingModal />
|
||||||
<PostStatusModal />
|
<PostStatusModal />
|
||||||
|
<EditStatusModal v-if="editingAvailable" />
|
||||||
|
<StatusHistoryModal v-if="editingAvailable" />
|
||||||
<SettingsModal />
|
<SettingsModal />
|
||||||
<div id="modal" />
|
<UpdateNotification />
|
||||||
<GlobalNoticeList />
|
<GlobalNoticeList />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -248,8 +248,10 @@ const getNodeInfo = async ({ store }) => {
|
||||||
store.dispatch('setInstanceOption', { name: 'mediaProxyAvailable', value: features.includes('media_proxy') })
|
store.dispatch('setInstanceOption', { name: 'mediaProxyAvailable', value: features.includes('media_proxy') })
|
||||||
store.dispatch('setInstanceOption', { name: 'safeDM', value: features.includes('safe_dm_mentions') })
|
store.dispatch('setInstanceOption', { name: 'safeDM', value: features.includes('safe_dm_mentions') })
|
||||||
store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
|
store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
|
||||||
|
store.dispatch('setInstanceOption', { name: 'editingAvailable', value: features.includes('editing') })
|
||||||
store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
|
store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
|
||||||
store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled })
|
store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled })
|
||||||
|
store.dispatch('setInstanceOption', { name: 'translationEnabled', value: features.includes('akkoma:machine_translation') })
|
||||||
|
|
||||||
const uploadLimits = metadata.uploadLimits
|
const uploadLimits = metadata.uploadLimits
|
||||||
store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })
|
store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })
|
||||||
|
@ -376,8 +378,9 @@ const afterStoreSetup = async ({ store, i18n }) => {
|
||||||
routes: routes(store),
|
routes: routes(store),
|
||||||
scrollBehavior: (to, _from, savedPosition) => {
|
scrollBehavior: (to, _from, savedPosition) => {
|
||||||
if (to.matched.some(m => m.meta.dontScroll)) {
|
if (to.matched.some(m => m.meta.dontScroll)) {
|
||||||
return false
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return savedPosition || { left: 0, top: 0 }
|
return savedPosition || { left: 0, top: 0 }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -58,7 +58,7 @@ export default (store) => {
|
||||||
component: RemoteUserResolver,
|
component: RemoteUserResolver,
|
||||||
beforeEnter: validateAuthenticatedRoute
|
beforeEnter: validateAuthenticatedRoute
|
||||||
},
|
},
|
||||||
{ name: 'external-user-profile', path: '/users/:id', component: UserProfile },
|
{ name: 'external-user-profile', path: '/users/:id', component: UserProfile, meta: { dontScroll: true } },
|
||||||
{ name: 'interactions', path: '/users/:username/interactions', component: Interactions, beforeEnter: validateAuthenticatedRoute },
|
{ name: 'interactions', path: '/users/:username/interactions', component: Interactions, beforeEnter: validateAuthenticatedRoute },
|
||||||
{ name: 'dms', path: '/users/:username/dms', component: DMs, beforeEnter: validateAuthenticatedRoute },
|
{ name: 'dms', path: '/users/:username/dms', component: DMs, beforeEnter: validateAuthenticatedRoute },
|
||||||
{ name: 'registration', path: '/registration', component: Registration },
|
{ name: 'registration', path: '/registration', component: Registration },
|
||||||
|
@ -75,7 +75,7 @@ export default (store) => {
|
||||||
{ name: 'list-timeline', path: '/lists/:id', component: ListTimeline },
|
{ name: 'list-timeline', path: '/lists/:id', component: ListTimeline },
|
||||||
{ name: 'list-edit', path: '/lists/:id/edit', component: ListEdit },
|
{ name: 'list-edit', path: '/lists/:id/edit', component: ListEdit },
|
||||||
{ name: 'announcements', path: '/announcements', component: AnnouncementsPage },
|
{ name: 'announcements', path: '/announcements', component: AnnouncementsPage },
|
||||||
{ name: 'user-profile', path: '/:_(users)?/:name', component: UserProfile }
|
{ name: 'user-profile', path: '/:_(users)?/:name', component: UserProfile, meta: { dontScroll: true } }
|
||||||
]
|
]
|
||||||
|
|
||||||
return routes
|
return routes
|
||||||
|
|
|
@ -13,6 +13,8 @@ const About = {
|
||||||
MRFTransparencyPanel
|
MRFTransparencyPanel
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
currentUser () { return this.$store.state.users.currentUser },
|
||||||
|
privateMode () { return this.$store.state.instance.private },
|
||||||
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
|
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
|
||||||
showInstanceSpecificPanel () {
|
showInstanceSpecificPanel () {
|
||||||
return this.$store.state.instance.showInstanceSpecificPanel &&
|
return this.$store.state.instance.showInstanceSpecificPanel &&
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="column-inner">
|
<div class="column-inner">
|
||||||
<instance-specific-panel v-if="showInstanceSpecificPanel" />
|
<!--<instance-specific-panel v-if="showInstanceSpecificPanel" />-->
|
||||||
<staff-panel />
|
<staff-panel v-if="currentUser || !privateMode" />
|
||||||
<terms-of-service-panel />
|
<terms-of-service-panel />
|
||||||
<MRFTransparencyPanel />
|
<MRFTransparencyPanel />
|
||||||
<features-panel v-if="showFeaturesPanel" />
|
<features-panel v-if="showFeaturesPanel" />
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import ProgressButton from '../progress_button/progress_button.vue'
|
import ProgressButton from '../progress_button/progress_button.vue'
|
||||||
import Popover from '../popover/popover.vue'
|
import Popover from '../popover/popover.vue'
|
||||||
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
import { mapState } from 'vuex'
|
||||||
import {
|
import {
|
||||||
faEllipsisV
|
faEllipsisV
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
@ -14,13 +16,22 @@ const AccountActions = {
|
||||||
'user', 'relationship'
|
'user', 'relationship'
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
return { }
|
return {
|
||||||
|
showingConfirmBlock: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
ProgressButton,
|
ProgressButton,
|
||||||
Popover
|
Popover,
|
||||||
|
ConfirmModal
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showConfirmBlock () {
|
||||||
|
this.showingConfirmBlock = true
|
||||||
|
},
|
||||||
|
hideConfirmBlock () {
|
||||||
|
this.showingConfirmBlock = false
|
||||||
|
},
|
||||||
showRepeats () {
|
showRepeats () {
|
||||||
this.$store.dispatch('showReblogs', this.user.id)
|
this.$store.dispatch('showReblogs', this.user.id)
|
||||||
},
|
},
|
||||||
|
@ -28,14 +39,33 @@ const AccountActions = {
|
||||||
this.$store.dispatch('hideReblogs', this.user.id)
|
this.$store.dispatch('hideReblogs', this.user.id)
|
||||||
},
|
},
|
||||||
blockUser () {
|
blockUser () {
|
||||||
|
if (!this.shouldConfirmBlock) {
|
||||||
|
this.doBlockUser()
|
||||||
|
} else {
|
||||||
|
this.showConfirmBlock()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doBlockUser () {
|
||||||
this.$store.dispatch('blockUser', this.user.id)
|
this.$store.dispatch('blockUser', this.user.id)
|
||||||
|
this.hideConfirmBlock()
|
||||||
},
|
},
|
||||||
unblockUser () {
|
unblockUser () {
|
||||||
this.$store.dispatch('unblockUser', this.user.id)
|
this.$store.dispatch('unblockUser', this.user.id)
|
||||||
},
|
},
|
||||||
|
removeUserFromFollowers () {
|
||||||
|
this.$store.dispatch('removeUserFromFollowers', this.user.id)
|
||||||
|
},
|
||||||
reportUser () {
|
reportUser () {
|
||||||
this.$store.dispatch('openUserReportingModal', { userId: this.user.id })
|
this.$store.dispatch('openUserReportingModal', { userId: this.user.id })
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
shouldConfirmBlock () {
|
||||||
|
return this.$store.getters.mergedConfig.modalOnBlock
|
||||||
|
},
|
||||||
|
...mapState({
|
||||||
|
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,13 @@
|
||||||
class="dropdown-divider"
|
class="dropdown-divider"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<button
|
||||||
|
v-if="relationship.followed_by"
|
||||||
|
class="btn button-default btn-block dropdown-item"
|
||||||
|
@click="removeUserFromFollowers"
|
||||||
|
>
|
||||||
|
{{ $t('user_card.remove_follower') }}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="relationship.blocking"
|
v-if="relationship.blocking"
|
||||||
class="btn button-default btn-block dropdown-item"
|
class="btn button-default btn-block dropdown-item"
|
||||||
|
@ -59,6 +66,27 @@
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
<teleport to="#modal">
|
||||||
|
<confirm-modal
|
||||||
|
v-if="showingConfirmBlock"
|
||||||
|
:title="$t('user_card.block_confirm_title')"
|
||||||
|
:confirm-text="$t('user_card.block_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('user_card.block_confirm_cancel_button')"
|
||||||
|
@accepted="doBlockUser"
|
||||||
|
@cancelled="hideConfirmBlock"
|
||||||
|
>
|
||||||
|
<i18n-t
|
||||||
|
keypath="user_card.block_confirm"
|
||||||
|
tag="span"
|
||||||
|
>
|
||||||
|
<template v-slot:user>
|
||||||
|
<span
|
||||||
|
v-text="user.screen_name_ui"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
</confirm-modal>
|
||||||
|
</teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="panel panel-default announcements-page">
|
<div class="panel panel-default announcements-page">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<span>
|
<div class="title">
|
||||||
{{ $t('announcements.page_header') }}
|
{{ $t('announcements.page_header') }}
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<section
|
<section
|
||||||
|
|
|
@ -132,6 +132,9 @@ const Attachment = {
|
||||||
...mapGetters(['mergedConfig'])
|
...mapGetters(['mergedConfig'])
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
'attachment.description' (newVal) {
|
||||||
|
this.localDescription = newVal
|
||||||
|
},
|
||||||
localDescription (newVal) {
|
localDescription (newVal) {
|
||||||
this.onEdit(newVal)
|
this.onEdit(newVal)
|
||||||
}
|
}
|
||||||
|
|
37
src/components/confirm_modal/confirm_modal.js
Normal file
37
src/components/confirm_modal/confirm_modal.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import DialogModal from '../dialog_modal/dialog_modal.vue'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component emits the following events:
|
||||||
|
* cancelled, emitted when the action should not be performed;
|
||||||
|
* accepted, emitted when the action should be performed;
|
||||||
|
*
|
||||||
|
* The caller should close this dialog after receiving any of the two events.
|
||||||
|
*/
|
||||||
|
const ConfirmModal = {
|
||||||
|
components: {
|
||||||
|
DialogModal
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
confirmText: {
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onCancel () {
|
||||||
|
this.$emit('cancelled')
|
||||||
|
},
|
||||||
|
onAccept () {
|
||||||
|
this.$emit('accepted')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ConfirmModal
|
39
src/components/confirm_modal/confirm_modal.vue
Normal file
39
src/components/confirm_modal/confirm_modal.vue
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<template>
|
||||||
|
<dialog-modal
|
||||||
|
v-body-scroll-lock="true"
|
||||||
|
class="confirm-modal"
|
||||||
|
:on-cancel="onCancel"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<span v-text="title" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<slot />
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<button
|
||||||
|
class="btn button-default"
|
||||||
|
@click.prevent="onCancel"
|
||||||
|
v-text="cancelText"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
class="btn button-default button-positive"
|
||||||
|
@click.prevent="onAccept"
|
||||||
|
v-text="confirmText"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</dialog-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../../_variables';
|
||||||
|
|
||||||
|
.confirm-modal {
|
||||||
|
.button-positive {
|
||||||
|
border: 3px solid var(--accent, $fallback--link);
|
||||||
|
border-radius: var(--btnRadius, $fallback--btnRadius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script src="./confirm_modal.js"></script>
|
|
@ -7,7 +7,11 @@ const conversationPage = {
|
||||||
computed: {
|
computed: {
|
||||||
statusId () {
|
statusId () {
|
||||||
return this.$route.params.id
|
return this.$route.params.id
|
||||||
}
|
},
|
||||||
|
currentUser () {
|
||||||
|
return this.$store.state.users.currentUser
|
||||||
|
},
|
||||||
|
privateMode () { return this.$store.state.instance.private }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="!currentUser && privateMode"
|
||||||
|
class="panel error-placeholder"
|
||||||
|
>
|
||||||
|
<div class="panel-heading">
|
||||||
|
<div class="title">
|
||||||
|
???
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body error">
|
||||||
|
<img
|
||||||
|
class="error-img"
|
||||||
|
src="/static/error.gif"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<conversation
|
<conversation
|
||||||
|
v-else
|
||||||
:collapsable="false"
|
:collapsable="false"
|
||||||
is-page="true"
|
is-page="true"
|
||||||
:status-id="statusId"
|
:status-id="statusId"
|
||||||
|
@ -7,3 +24,23 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./conversation-page.js"></script>
|
<script src="./conversation-page.js"></script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.error-placeholder {
|
||||||
|
.panel-body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: middle;
|
||||||
|
padding: 7em;
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
padding: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-img {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 0px 0px 10px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { reduce, filter, findIndex, clone, get } from 'lodash'
|
import { reduce, filter, findIndex, clone, get } from 'lodash'
|
||||||
import Status from '../status/status.vue'
|
import Status from '../status/status.vue'
|
||||||
import ThreadTree from '../thread_tree/thread_tree.vue'
|
import ThreadTree from '../thread_tree/thread_tree.vue'
|
||||||
|
import { WSConnectionStatus } from '../../services/api/api.service.js'
|
||||||
|
import { mapGetters, mapState } from 'vuex'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
@ -77,6 +79,9 @@ const conversation = {
|
||||||
const maxDepth = this.$store.getters.mergedConfig.maxDepthInThread - 2
|
const maxDepth = this.$store.getters.mergedConfig.maxDepthInThread - 2
|
||||||
return maxDepth >= 1 ? maxDepth : 1
|
return maxDepth >= 1 ? maxDepth : 1
|
||||||
},
|
},
|
||||||
|
streamingEnabled () {
|
||||||
|
return this.mergedConfig.useStreamingApi && this.mastoUserSocketStatus === WSConnectionStatus.JOINED
|
||||||
|
},
|
||||||
displayStyle () {
|
displayStyle () {
|
||||||
return this.$store.getters.mergedConfig.conversationDisplay
|
return this.$store.getters.mergedConfig.conversationDisplay
|
||||||
},
|
},
|
||||||
|
@ -339,7 +344,11 @@ const conversation = {
|
||||||
},
|
},
|
||||||
maybeHighlight () {
|
maybeHighlight () {
|
||||||
return this.isExpanded ? this.highlight : null
|
return this.isExpanded ? this.highlight : null
|
||||||
}
|
},
|
||||||
|
...mapGetters(['mergedConfig']),
|
||||||
|
...mapState({
|
||||||
|
mastoUserSocketStatus: state => state.api.mastoUserSocketStatus
|
||||||
|
})
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Status,
|
Status,
|
||||||
|
@ -395,6 +404,11 @@ const conversation = {
|
||||||
setHighlight (id) {
|
setHighlight (id) {
|
||||||
if (!id) return
|
if (!id) return
|
||||||
this.highlight = id
|
this.highlight = id
|
||||||
|
|
||||||
|
if (!this.streamingEnabled) {
|
||||||
|
this.$store.dispatch('fetchStatus', id)
|
||||||
|
}
|
||||||
|
|
||||||
this.$store.dispatch('fetchFavsAndRepeats', id)
|
this.$store.dispatch('fetchFavsAndRepeats', id)
|
||||||
this.$store.dispatch('fetchEmojiReactionsBy', id)
|
this.$store.dispatch('fetchEmojiReactionsBy', id)
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import SearchBar from 'components/search_bar/search_bar.vue'
|
import SearchBar from 'components/search_bar/search_bar.vue'
|
||||||
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faSignInAlt,
|
faSignInAlt,
|
||||||
|
@ -11,6 +12,11 @@ import {
|
||||||
faSearch,
|
faSearch,
|
||||||
faTachometerAlt,
|
faTachometerAlt,
|
||||||
faCog,
|
faCog,
|
||||||
|
faGlobe,
|
||||||
|
faBolt,
|
||||||
|
faUsers,
|
||||||
|
faCommentMedical,
|
||||||
|
faBookmark,
|
||||||
faInfoCircle
|
faInfoCircle
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
@ -25,12 +31,18 @@ library.add(
|
||||||
faSearch,
|
faSearch,
|
||||||
faTachometerAlt,
|
faTachometerAlt,
|
||||||
faCog,
|
faCog,
|
||||||
|
faGlobe,
|
||||||
|
faBolt,
|
||||||
|
faUsers,
|
||||||
|
faCommentMedical,
|
||||||
|
faBookmark,
|
||||||
faInfoCircle
|
faInfoCircle
|
||||||
)
|
)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
SearchBar
|
SearchBar,
|
||||||
|
ConfirmModal
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
searchBarHidden: true,
|
searchBarHidden: true,
|
||||||
|
@ -40,7 +52,8 @@ export default {
|
||||||
window.CSS.supports('-moz-mask-size', 'contain') ||
|
window.CSS.supports('-moz-mask-size', 'contain') ||
|
||||||
window.CSS.supports('-ms-mask-size', 'contain') ||
|
window.CSS.supports('-ms-mask-size', 'contain') ||
|
||||||
window.CSS.supports('-o-mask-size', 'contain')
|
window.CSS.supports('-o-mask-size', 'contain')
|
||||||
)
|
),
|
||||||
|
showingConfirmLogout: false
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
enableMask () { return this.supportsMask && this.$store.state.instance.logoMask },
|
enableMask () { return this.supportsMask && this.$store.state.instance.logoMask },
|
||||||
|
@ -65,20 +78,34 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
logo () { return this.$store.state.instance.logo },
|
logo () { return this.$store.state.instance.logo },
|
||||||
|
mergedConfig () {
|
||||||
|
return this.$store.getters.mergedConfig
|
||||||
|
},
|
||||||
sitename () { return this.$store.state.instance.name },
|
sitename () { return this.$store.state.instance.name },
|
||||||
|
showNavShortcuts () {
|
||||||
|
return this.mergedConfig.showNavShortcuts
|
||||||
|
},
|
||||||
|
showWiderShortcuts () {
|
||||||
|
return this.mergedConfig.showWiderShortcuts
|
||||||
|
},
|
||||||
|
hideSiteFavicon () {
|
||||||
|
return this.mergedConfig.hideSiteFavicon
|
||||||
|
},
|
||||||
|
hideSiteName () {
|
||||||
|
return this.mergedConfig.hideSiteName
|
||||||
|
},
|
||||||
hideSitename () { return this.$store.state.instance.hideSitename },
|
hideSitename () { return this.$store.state.instance.hideSitename },
|
||||||
logoLeft () { return this.$store.state.instance.logoLeft },
|
logoLeft () { return this.$store.state.instance.logoLeft },
|
||||||
currentUser () { return this.$store.state.users.currentUser },
|
currentUser () { return this.$store.state.users.currentUser },
|
||||||
privateMode () { return this.$store.state.instance.private }
|
privateMode () { return this.$store.state.instance.private },
|
||||||
|
shouldConfirmLogout () {
|
||||||
|
return this.$store.getters.mergedConfig.modalOnLogout
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
scrollToTop () {
|
scrollToTop () {
|
||||||
window.scrollTo(0, 0)
|
window.scrollTo(0, 0)
|
||||||
},
|
},
|
||||||
logout () {
|
|
||||||
this.$router.replace('/main/public')
|
|
||||||
this.$store.dispatch('logout')
|
|
||||||
},
|
|
||||||
onSearchBarToggled (hidden) {
|
onSearchBarToggled (hidden) {
|
||||||
this.searchBarHidden = hidden
|
this.searchBarHidden = hidden
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,16 +15,16 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: var(--navbar-height);
|
grid-template-rows: var(--navbar-height);
|
||||||
grid-template-columns: 2fr auto 2fr;
|
grid-template-columns: 2fr auto 2fr;
|
||||||
grid-template-areas: "sitename logo actions";
|
grid-template-areas: "nav-left logo actions";
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0 1.2em;
|
padding: 0 1.2em;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-width: 980px;
|
max-width: 1110px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.-logoLeft .inner-nav {
|
&.-logoLeft .inner-nav {
|
||||||
grid-template-columns: auto 2fr 2fr;
|
grid-template-columns: auto 2fr 2fr;
|
||||||
grid-template-areas: "logo sitename actions";
|
grid-template-areas: "logo nav-left actions";
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-default {
|
.button-default {
|
||||||
|
@ -84,24 +84,52 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-icon {
|
.nav-icon {
|
||||||
margin-left: 1em;
|
margin-left: 0.2em;
|
||||||
width: 2em;
|
width: 2em;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-size: 130%;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
&-logout {
|
&-logout {
|
||||||
margin-left: 2em;
|
margin-left: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.router-link-active {
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin-top: 0.05em;
|
||||||
|
|
||||||
|
.svg-inline--fa {
|
||||||
|
font-weight: bolder;
|
||||||
|
color: $fallback--text;
|
||||||
|
color: var(--selectedMenuText, $fallback--text);
|
||||||
|
--lightText: var(--selectedMenuLightText, $fallback--lightText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.svg-inline--fa {
|
.svg-inline--fa {
|
||||||
color: $fallback--link;
|
color: $fallback--link;
|
||||||
color: var(--topBarLink, $fallback--link);
|
color: var(--topBarLink, $fallback--link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sitename {
|
.-wide {
|
||||||
grid-area: sitename;
|
.nav-icon {
|
||||||
|
margin-left: 0.7em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
padding-left: 5px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-left-wrapper {
|
||||||
|
grid-area: nav-left;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 28px;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
|
@ -120,5 +148,10 @@
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
justify-content: flex-start;
|
||||||
|
text-alignt: left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,79 @@
|
||||||
:class="{ '-logoLeft': logoLeft }"
|
:class="{ '-logoLeft': logoLeft }"
|
||||||
@click="scrollToTop()"
|
@click="scrollToTop()"
|
||||||
>
|
>
|
||||||
<div class="inner-nav">
|
<div
|
||||||
<div class="item sitename">
|
class="inner-nav"
|
||||||
|
:class="{ '-wide': showWiderShortcuts }"
|
||||||
|
>
|
||||||
|
<div class="item nav-left-wrapper">
|
||||||
<router-link
|
<router-link
|
||||||
v-if="!hideSitename"
|
class="site-brand"
|
||||||
class="site-name"
|
|
||||||
:to="{ name: 'root' }"
|
:to="{ name: 'root' }"
|
||||||
active-class="home"
|
active-class="home"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
v-if="!hideSiteFavicon"
|
||||||
|
class="favicon"
|
||||||
|
src="/favicon.png"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="!hideSiteName"
|
||||||
|
class="site-name"
|
||||||
>
|
>
|
||||||
{{ sitename }}
|
{{ sitename }}
|
||||||
|
</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<div
|
||||||
|
v-if="(currentUser || !privateMode) && showNavShortcuts"
|
||||||
|
class="nav-items left"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
v-if="currentUser"
|
||||||
|
:to="{ name: 'friends' }"
|
||||||
|
class="nav-icon"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="home"
|
||||||
|
:title="$t('nav.home_timeline')"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
:to="{ name: 'public-timeline' }"
|
||||||
|
class="nav-icon"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="users"
|
||||||
|
:title="$t('nav.public_tl')"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
:to="{ name: 'public-external-timeline' }"
|
||||||
|
class="nav-icon"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="globe"
|
||||||
|
:title="$t('nav.twkn')"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
v-if="currentUser"
|
||||||
|
:to="{ name: 'bubble-timeline' }"
|
||||||
|
class="nav-icon"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="comment-medical"
|
||||||
|
:title="$t('nav.bubble_timeline')"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<router-link
|
<router-link
|
||||||
class="logo"
|
class="logo"
|
||||||
|
@ -36,6 +99,46 @@
|
||||||
@toggled="onSearchBarToggled"
|
@toggled="onSearchBarToggled"
|
||||||
@click.stop
|
@click.stop
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
v-if="(currentUser || !privateMode) && showNavShortcuts"
|
||||||
|
class="nav-items right"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
class="nav-icon"
|
||||||
|
:to="{ name: 'interactions', params: { username: currentUser.screen_name } }"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="bolt"
|
||||||
|
:title="$t('nav.interactions')"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
v-if="currentUser"
|
||||||
|
:to="{ name: 'lists' }"
|
||||||
|
class="nav-icon"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="list"
|
||||||
|
:title="$t('nav.lists')"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
v-if="currentUser"
|
||||||
|
:to="{ name: 'bookmarks' }"
|
||||||
|
class="nav-icon"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="bookmark"
|
||||||
|
:title="$t('nav.bookmarks')"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
class="button-unstyled nav-icon"
|
class="button-unstyled nav-icon"
|
||||||
@click.stop="openSettingsModal"
|
@click.stop="openSettingsModal"
|
||||||
|
@ -61,20 +164,20 @@
|
||||||
:title="$t('nav.administration')"
|
:title="$t('nav.administration')"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
<button
|
</div>
|
||||||
v-if="currentUser"
|
</div>
|
||||||
class="button-unstyled nav-icon nav-icon-logout"
|
<teleport to="#modal">
|
||||||
@click.prevent="logout"
|
<confirm-modal
|
||||||
|
v-if="showingConfirmLogout"
|
||||||
|
:title="$t('login.logout_confirm_title')"
|
||||||
|
:confirm-text="$t('login.logout_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('login.logout_confirm_cancel_button')"
|
||||||
|
@accepted="doLogout"
|
||||||
|
@cancelled="hideConfirmLogout"
|
||||||
>
|
>
|
||||||
<FAIcon
|
{{ $t('login.logout_confirm') }}
|
||||||
fixed-width
|
</confirm-modal>
|
||||||
class="fa-scale-110 fa-old-padding"
|
</teleport>
|
||||||
icon="sign-out-alt"
|
|
||||||
:title="$t('login.logout')"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
<script src="./desktop_nav.js"></script>
|
<script src="./desktop_nav.js"></script>
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: rgba(27,31,35,.5);
|
background: rgba(27,31,35,.5);
|
||||||
z-index: 99;
|
z-index: 2000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
margin: 15vh auto;
|
margin: 15vh auto;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
z-index: 999;
|
z-index: 2001;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
display: block;
|
display: block;
|
||||||
background-color: $fallback--bg;
|
background-color: $fallback--bg;
|
||||||
|
|
75
src/components/edit_status_modal/edit_status_modal.js
Normal file
75
src/components/edit_status_modal/edit_status_modal.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
import PostStatusForm from '../post_status_form/post_status_form.vue'
|
||||||
|
import Modal from '../modal/modal.vue'
|
||||||
|
import statusPosterService from '../../services/status_poster/status_poster.service.js'
|
||||||
|
import get from 'lodash/get'
|
||||||
|
|
||||||
|
const EditStatusModal = {
|
||||||
|
components: {
|
||||||
|
PostStatusForm,
|
||||||
|
Modal
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
resettingForm: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isLoggedIn () {
|
||||||
|
return !!this.$store.state.users.currentUser
|
||||||
|
},
|
||||||
|
modalActivated () {
|
||||||
|
return this.$store.state.editStatus.modalActivated
|
||||||
|
},
|
||||||
|
isFormVisible () {
|
||||||
|
return this.isLoggedIn && !this.resettingForm && this.modalActivated
|
||||||
|
},
|
||||||
|
params () {
|
||||||
|
return this.$store.state.editStatus.params || {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
params (newVal, oldVal) {
|
||||||
|
if (get(newVal, 'statusId') !== get(oldVal, 'statusId')) {
|
||||||
|
this.resettingForm = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.resettingForm = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isFormVisible (val) {
|
||||||
|
if (val) {
|
||||||
|
this.$nextTick(() => this.$el && this.$el.querySelector('textarea').focus())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
doEditStatus ({ status, spoilerText, sensitive, media, contentType, poll }) {
|
||||||
|
const params = {
|
||||||
|
store: this.$store,
|
||||||
|
statusId: this.$store.state.editStatus.params.statusId,
|
||||||
|
status,
|
||||||
|
spoilerText,
|
||||||
|
sensitive,
|
||||||
|
poll,
|
||||||
|
media,
|
||||||
|
contentType
|
||||||
|
}
|
||||||
|
|
||||||
|
return statusPosterService.editStatus(params)
|
||||||
|
.then((data) => {
|
||||||
|
return data
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('Error editing status', err)
|
||||||
|
return {
|
||||||
|
error: err.message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
closeModal () {
|
||||||
|
this.$store.dispatch('closeEditStatusModal')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditStatusModal
|
48
src/components/edit_status_modal/edit_status_modal.vue
Normal file
48
src/components/edit_status_modal/edit_status_modal.vue
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<template>
|
||||||
|
<Modal
|
||||||
|
v-if="isFormVisible"
|
||||||
|
class="edit-form-modal-view"
|
||||||
|
@backdropClicked="closeModal"
|
||||||
|
>
|
||||||
|
<div class="edit-form-modal-panel panel">
|
||||||
|
<div class="panel-heading">
|
||||||
|
{{ $t('post_status.edit_status') }}
|
||||||
|
</div>
|
||||||
|
<PostStatusForm
|
||||||
|
class="panel-body"
|
||||||
|
v-bind="params"
|
||||||
|
@posted="closeModal"
|
||||||
|
:disablePolls="true"
|
||||||
|
:disableVisibilitySelector="true"
|
||||||
|
:post-handler="doEditStatus"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./edit_status_modal.js"></script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.modal-view.edit-form-modal-view {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.edit-form-modal-panel {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 25%;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 700px;
|
||||||
|
|
||||||
|
@media (orientation: landscape) {
|
||||||
|
margin-top: 8%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-bottom-left {
|
||||||
|
max-width: 6.5em;
|
||||||
|
|
||||||
|
.emoji-icon {
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -88,9 +88,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.emoji-picker-panel {
|
.emoji-picker-panel {
|
||||||
position: absolute;
|
position: relative;
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
|
top: 0px !important;
|
||||||
|
|
||||||
&.hide {
|
&.hide {
|
||||||
display: none
|
display: none
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
faStickyNote,
|
faStickyNote,
|
||||||
faSmileBeam
|
faSmileBeam
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { trim } from 'lodash'
|
import { trim, escapeRegExp, startCase } from 'lodash'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
faBoxOpen,
|
faBoxOpen,
|
||||||
|
@ -21,23 +21,6 @@ const LOAD_EMOJI_BY = 60
|
||||||
// When to start loading new batch emoji, in pixels
|
// When to start loading new batch emoji, in pixels
|
||||||
const LOAD_EMOJI_MARGIN = 64
|
const LOAD_EMOJI_MARGIN = 64
|
||||||
|
|
||||||
const filterByKeyword = (list, keyword = '') => {
|
|
||||||
if (keyword === '') return list
|
|
||||||
|
|
||||||
const keywordLowercase = keyword.toLowerCase()
|
|
||||||
let orderedEmojiList = []
|
|
||||||
for (const emoji of list) {
|
|
||||||
const indexOfKeyword = emoji.displayText.toLowerCase().indexOf(keywordLowercase)
|
|
||||||
if (indexOfKeyword > -1) {
|
|
||||||
if (!Array.isArray(orderedEmojiList[indexOfKeyword])) {
|
|
||||||
orderedEmojiList[indexOfKeyword] = []
|
|
||||||
}
|
|
||||||
orderedEmojiList[indexOfKeyword].push(emoji)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return orderedEmojiList.flat()
|
|
||||||
}
|
|
||||||
|
|
||||||
const EmojiPicker = {
|
const EmojiPicker = {
|
||||||
props: {
|
props: {
|
||||||
enableStickerPicker: {
|
enableStickerPicker: {
|
||||||
|
@ -49,7 +32,7 @@ const EmojiPicker = {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
keyword: '',
|
keyword: '',
|
||||||
activeGroup: 'custom',
|
activeGroup: 'standard',
|
||||||
showingStickers: false,
|
showingStickers: false,
|
||||||
groupsScrolledClass: 'scrolled-top',
|
groupsScrolledClass: 'scrolled-top',
|
||||||
keepOpen: false,
|
keepOpen: false,
|
||||||
|
@ -80,13 +63,8 @@ const EmojiPicker = {
|
||||||
this.triggerLoadMore(target)
|
this.triggerLoadMore(target)
|
||||||
},
|
},
|
||||||
highlight (key) {
|
highlight (key) {
|
||||||
const ref = this.$refs['group-' + key]
|
|
||||||
const top = ref.offsetTop
|
|
||||||
this.setShowStickers(false)
|
this.setShowStickers(false)
|
||||||
this.activeGroup = key
|
this.activeGroup = key
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs['emoji-groups'].scrollTop = top + 1
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
updateScrolledClass (target) {
|
updateScrolledClass (target) {
|
||||||
if (target.scrollTop <= 5) {
|
if (target.scrollTop <= 5) {
|
||||||
|
@ -155,6 +133,13 @@ const EmojiPicker = {
|
||||||
},
|
},
|
||||||
setShowStickers (value) {
|
setShowStickers (value) {
|
||||||
this.showingStickers = value
|
this.showingStickers = value
|
||||||
|
},
|
||||||
|
filterByKeyword (list) {
|
||||||
|
if (this.keyword === '') return list
|
||||||
|
const regex = new RegExp(escapeRegExp(trim(this.keyword)), 'i')
|
||||||
|
return list.filter(emoji => {
|
||||||
|
return regex.test(emoji.displayText)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -175,9 +160,8 @@ const EmojiPicker = {
|
||||||
return 0
|
return 0
|
||||||
},
|
},
|
||||||
filteredEmoji () {
|
filteredEmoji () {
|
||||||
return filterByKeyword(
|
return this.filterByKeyword(
|
||||||
this.$store.state.instance.customEmoji || [],
|
this.$store.state.instance.customEmoji || []
|
||||||
trim(this.keyword)
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
customEmojiBuffer () {
|
customEmojiBuffer () {
|
||||||
|
@ -185,25 +169,50 @@ const EmojiPicker = {
|
||||||
},
|
},
|
||||||
emojis () {
|
emojis () {
|
||||||
const standardEmojis = this.$store.state.instance.emoji || []
|
const standardEmojis = this.$store.state.instance.emoji || []
|
||||||
const customEmojis = this.customEmojiBuffer
|
const customEmojis = this.sortedEmoji
|
||||||
|
const emojiPacks = []
|
||||||
|
customEmojis.forEach((pack, id) => {
|
||||||
|
emojiPacks.push({
|
||||||
|
id: id.replace(/^pack:/, ''),
|
||||||
|
text: startCase(id.replace(/^pack:/, '')),
|
||||||
|
first: pack[0],
|
||||||
|
emojis: this.filterByKeyword(pack)
|
||||||
|
})
|
||||||
|
})
|
||||||
return [
|
return [
|
||||||
{
|
|
||||||
id: 'custom',
|
|
||||||
text: this.$t('emoji.custom'),
|
|
||||||
icon: 'smile-beam',
|
|
||||||
emojis: customEmojis
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'standard',
|
id: 'standard',
|
||||||
text: this.$t('emoji.unicode'),
|
text: this.$t('emoji.unicode'),
|
||||||
icon: 'box-open',
|
first: {
|
||||||
emojis: filterByKeyword(standardEmojis, trim(this.keyword))
|
imageUrl: '',
|
||||||
|
replacement: '🥴'
|
||||||
|
},
|
||||||
|
emojis: this.filterByKeyword(standardEmojis)
|
||||||
}
|
}
|
||||||
]
|
].concat(emojiPacks)
|
||||||
|
},
|
||||||
|
sortedEmoji () {
|
||||||
|
const customEmojis = this.$store.state.instance.customEmoji || []
|
||||||
|
const sortedEmojiGroups = new Map()
|
||||||
|
customEmojis.forEach((emoji) => {
|
||||||
|
if (!sortedEmojiGroups.has(emoji.tags[0])) {
|
||||||
|
sortedEmojiGroups.set(emoji.tags[0], [emoji])
|
||||||
|
} else {
|
||||||
|
sortedEmojiGroups.get(emoji.tags[0]).push(emoji)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return new Map([...sortedEmojiGroups.entries()].sort())
|
||||||
},
|
},
|
||||||
emojisView () {
|
emojisView () {
|
||||||
return this.emojis.filter(value => value.emojis.length > 0)
|
if (this.keyword === '') {
|
||||||
|
return this.emojis.filter(pack => {
|
||||||
|
return pack.id === this.activeGroup
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return this.emojis.filter(pack => {
|
||||||
|
return pack.emojis.length > 0
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
stickerPickerEnabled () {
|
stickerPickerEnabled () {
|
||||||
return (this.$store.state.instance.stickers || []).length !== 0
|
return (this.$store.state.instance.stickers || []).length !== 0
|
||||||
|
|
|
@ -35,9 +35,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
display: flex;
|
margin-top: 10px;
|
||||||
height: 32px;
|
height: 5.8em;
|
||||||
padding: 10px 7px 5px;
|
}
|
||||||
|
|
||||||
|
.emoji-header {
|
||||||
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
@ -65,15 +68,34 @@
|
||||||
|
|
||||||
.additional-tabs,
|
.additional-tabs,
|
||||||
.emoji-tabs {
|
.emoji-tabs {
|
||||||
|
position: absolute;
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 0;
|
flex-wrap: nowrap;
|
||||||
flex-basis: auto;
|
|
||||||
flex-shrink: 1;
|
overflow: auto;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
&-item {
|
&-item {
|
||||||
padding: 0 7px;
|
vertical-align: top;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
padding: .4em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1.85em;
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 1.9em;
|
||||||
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="emoji-picker panel panel-default panel-body">
|
<div class="emoji-picker panel panel-default panel-body">
|
||||||
<div class="heading">
|
<div class="heading">
|
||||||
|
<span class="emoji-header">Emoji Packs</span>
|
||||||
<span class="emoji-tabs">
|
<span class="emoji-tabs">
|
||||||
<span
|
<span
|
||||||
v-for="group in emojis"
|
v-for="group in emojis"
|
||||||
|
@ -13,10 +14,11 @@
|
||||||
:title="group.text"
|
:title="group.text"
|
||||||
@click.prevent="highlight(group.id)"
|
@click.prevent="highlight(group.id)"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<span v-if="!group.first.imageUrl">{{ group.first.replacement }}</span>
|
||||||
:icon="group.icon"
|
<img
|
||||||
fixed-width
|
v-else
|
||||||
/>
|
:src="group.first.imageUrl"
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
|
|
|
@ -27,7 +27,11 @@ const EmojiReactions = {
|
||||||
},
|
},
|
||||||
accountsForEmoji () {
|
accountsForEmoji () {
|
||||||
return this.status.emoji_reactions.reduce((acc, reaction) => {
|
return this.status.emoji_reactions.reduce((acc, reaction) => {
|
||||||
|
if (reaction.url) {
|
||||||
|
acc[reaction.url] = reaction.accounts || []
|
||||||
|
} else {
|
||||||
acc[reaction.name] = reaction.accounts || []
|
acc[reaction.name] = reaction.accounts || []
|
||||||
|
}
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
},
|
},
|
||||||
|
@ -42,6 +46,14 @@ const EmojiReactions = {
|
||||||
reactedWith (emoji) {
|
reactedWith (emoji) {
|
||||||
return this.status.emoji_reactions.find(r => r.name === emoji).me
|
return this.status.emoji_reactions.find(r => r.name === emoji).me
|
||||||
},
|
},
|
||||||
|
isLocalReaction (emojiUrl) {
|
||||||
|
if (!emojiUrl) return true
|
||||||
|
const reacted = this.accountsForEmoji[emojiUrl]
|
||||||
|
if (reacted.length === 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return reacted[0].is_local
|
||||||
|
},
|
||||||
fetchEmojiReactionsByIfMissing () {
|
fetchEmojiReactionsByIfMissing () {
|
||||||
const hasNoAccounts = this.status.emoji_reactions.find(r => !r.accounts)
|
const hasNoAccounts = this.status.emoji_reactions.find(r => !r.accounts)
|
||||||
if (hasNoAccounts) {
|
if (hasNoAccounts) {
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
<div class="emoji-reactions">
|
<div class="emoji-reactions">
|
||||||
<UserListPopover
|
<UserListPopover
|
||||||
v-for="(reaction) in emojiReactions"
|
v-for="(reaction) in emojiReactions"
|
||||||
:key="reaction.name"
|
:key="reaction.url || reaction.name"
|
||||||
:users="accountsForEmoji[reaction.name]"
|
:users="accountsForEmoji[reaction.url || reaction.name]"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="emoji-reaction btn button-default"
|
class="emoji-reaction btn button-default"
|
||||||
:class="{ 'picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }"
|
:class="{ 'picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }"
|
||||||
|
:disabled="!isLocalReaction(reaction.url)"
|
||||||
@click="emojiOnClick(reaction.name, $event)"
|
@click="emojiOnClick(reaction.name, $event)"
|
||||||
@mouseenter="fetchEmojiReactionsByIfMissing()"
|
@mouseenter="fetchEmojiReactionsByIfMissing()"
|
||||||
>
|
>
|
||||||
|
@ -56,13 +57,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-reaction {
|
.emoji-reaction {
|
||||||
padding: 0 0.5em;
|
padding: 1px 6px;
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
font-size: 0.7em !important;
|
||||||
|
height: 30px;
|
||||||
.reaction-emoji {
|
.reaction-emoji {
|
||||||
width: 2.55em !important;
|
width: 2.55em !important;
|
||||||
margin-right: 0.25em;
|
margin-right: 0.25em;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Popover from '../popover/popover.vue'
|
import Popover from '../popover/popover.vue'
|
||||||
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faEllipsisH,
|
faEllipsisH,
|
||||||
|
@ -6,7 +7,9 @@ import {
|
||||||
faEyeSlash,
|
faEyeSlash,
|
||||||
faThumbtack,
|
faThumbtack,
|
||||||
faShareAlt,
|
faShareAlt,
|
||||||
faExternalLinkAlt
|
faQuoteLeft,
|
||||||
|
faExternalLinkAlt,
|
||||||
|
faHistory
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import {
|
import {
|
||||||
faBookmark as faBookmarkReg,
|
faBookmark as faBookmarkReg,
|
||||||
|
@ -20,20 +23,49 @@ library.add(
|
||||||
faEyeSlash,
|
faEyeSlash,
|
||||||
faThumbtack,
|
faThumbtack,
|
||||||
faShareAlt,
|
faShareAlt,
|
||||||
|
faQuoteLeft,
|
||||||
faExternalLinkAlt,
|
faExternalLinkAlt,
|
||||||
faFlag
|
faFlag,
|
||||||
|
faHistory
|
||||||
)
|
)
|
||||||
|
|
||||||
const ExtraButtons = {
|
const ExtraButtons = {
|
||||||
props: ['status'],
|
props: ['status'],
|
||||||
components: { Popover },
|
components: {
|
||||||
|
Popover,
|
||||||
|
ConfirmModal
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
expanded: false,
|
||||||
|
showingDeleteDialog: false
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
deleteStatus () {
|
deleteStatus () {
|
||||||
const confirmed = window.confirm(this.$t('status.delete_confirm'))
|
if (this.shouldConfirmDelete) {
|
||||||
if (confirmed) {
|
this.showDeleteStatusConfirmDialog()
|
||||||
this.$store.dispatch('deleteStatus', { id: this.status.id })
|
} else {
|
||||||
|
this.doDeleteStatus()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
doDeleteStatus () {
|
||||||
|
this.$store.dispatch('deleteStatus', { id: this.status.id })
|
||||||
|
this.hideDeleteStatusConfirmDialog()
|
||||||
|
},
|
||||||
|
showDeleteStatusConfirmDialog () {
|
||||||
|
this.showingDeleteDialog = true
|
||||||
|
},
|
||||||
|
hideDeleteStatusConfirmDialog () {
|
||||||
|
this.showingDeleteDialog = false
|
||||||
|
},
|
||||||
|
|
||||||
|
translateStatus () {
|
||||||
|
const translateTo = this.$store.getters.mergedConfig.translationLanguage || this.$store.state.instance.interfaceLanguage
|
||||||
|
this.$store.dispatch('translateStatus', { id: this.status.id, language: translateTo })
|
||||||
|
.then(() => this.$emit('onSuccess'))
|
||||||
|
.catch(err => this.$emit('onError', err.error.error))
|
||||||
|
},
|
||||||
pinStatus () {
|
pinStatus () {
|
||||||
this.$store.dispatch('pinStatus', this.status.id)
|
this.$store.dispatch('pinStatus', this.status.id)
|
||||||
.then(() => this.$emit('onSuccess'))
|
.then(() => this.$emit('onSuccess'))
|
||||||
|
@ -71,6 +103,25 @@ const ExtraButtons = {
|
||||||
},
|
},
|
||||||
reportStatus () {
|
reportStatus () {
|
||||||
this.$store.dispatch('openUserReportingModal', { userId: this.status.user.id, statusIds: [this.status.id] })
|
this.$store.dispatch('openUserReportingModal', { userId: this.status.user.id, statusIds: [this.status.id] })
|
||||||
|
},
|
||||||
|
editStatus () {
|
||||||
|
this.$store.dispatch('fetchStatusSource', { id: this.status.id })
|
||||||
|
.then(data => this.$store.dispatch('openEditStatusModal', {
|
||||||
|
statusId: this.status.id,
|
||||||
|
subject: data.spoiler_text,
|
||||||
|
statusText: data.text,
|
||||||
|
statusIsSensitive: this.status.nsfw,
|
||||||
|
statusPoll: this.status.poll,
|
||||||
|
statusFiles: [...this.status.attachments],
|
||||||
|
visibility: this.status.visibility,
|
||||||
|
statusContentType: data.content_type
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
showStatusHistory () {
|
||||||
|
const originalStatus = { ...this.status }
|
||||||
|
const stripFieldsList = ['attachments', 'created_at', 'emojis', 'text', 'raw_html', 'nsfw', 'poll', 'summary', 'summary_raw_html']
|
||||||
|
stripFieldsList.forEach(p => delete originalStatus[p])
|
||||||
|
this.$store.dispatch('openStatusHistoryModal', originalStatus)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -89,9 +140,23 @@ const ExtraButtons = {
|
||||||
canMute () {
|
canMute () {
|
||||||
return !!this.currentUser
|
return !!this.currentUser
|
||||||
},
|
},
|
||||||
|
canTranslate () {
|
||||||
|
return this.$store.state.instance.translationEnabled === true
|
||||||
|
},
|
||||||
statusLink () {
|
statusLink () {
|
||||||
|
if (this.status.is_local) {
|
||||||
return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}`
|
return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}`
|
||||||
|
} else {
|
||||||
|
return this.status.external_url
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
shouldConfirmDelete () {
|
||||||
|
return this.$store.getters.mergedConfig.modalOnDelete
|
||||||
|
},
|
||||||
|
isEdited () {
|
||||||
|
return this.status.edited_at !== null
|
||||||
|
},
|
||||||
|
editingAvailable () { return this.$store.state.instance.editingAvailable }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,28 @@
|
||||||
icon="bookmark"
|
icon="bookmark"
|
||||||
/><span>{{ $t("status.unbookmark") }}</span>
|
/><span>{{ $t("status.unbookmark") }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="ownStatus && editingAvailable"
|
||||||
|
class="button-default dropdown-item dropdown-item-icon"
|
||||||
|
@click.prevent="editStatus"
|
||||||
|
@click="close"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
icon="pen"
|
||||||
|
/><span>{{ $t("status.edit") }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="isEdited && editingAvailable"
|
||||||
|
class="button-default dropdown-item dropdown-item-icon"
|
||||||
|
@click.prevent="showStatusHistory"
|
||||||
|
@click="close"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
icon="history"
|
||||||
|
/><span>{{ $t("status.edit_history") }}</span>
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="canDelete"
|
v-if="canDelete"
|
||||||
class="button-default dropdown-item dropdown-item-icon"
|
class="button-default dropdown-item dropdown-item-icon"
|
||||||
|
@ -116,6 +138,28 @@
|
||||||
:icon="['far', 'flag']"
|
:icon="['far', 'flag']"
|
||||||
/><span>{{ $t("user_card.report") }}</span>
|
/><span>{{ $t("user_card.report") }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="(status.visibility === 'public' || status.visibility === 'unlisted')"
|
||||||
|
class="button-default dropdown-item dropdown-item-icon extra-quote"
|
||||||
|
@click.prevent="$emit('quote-toggle')"
|
||||||
|
@click="close"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
icon="quote-left"
|
||||||
|
/><span>{{ $t("tool_tip.quote") }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="canTranslate"
|
||||||
|
class="button-default dropdown-item dropdown-item-icon"
|
||||||
|
@click.prevent="translateStatus"
|
||||||
|
@click="close"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
icon="globe"
|
||||||
|
/><span>{{ $t("status.translate") }}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:trigger>
|
<template v-slot:trigger>
|
||||||
|
@ -125,6 +169,18 @@
|
||||||
icon="ellipsis-h"
|
icon="ellipsis-h"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
<teleport to="#modal">
|
||||||
|
<ConfirmModal
|
||||||
|
v-if="showingDeleteDialog"
|
||||||
|
:title="$t('status.delete_confirm_title')"
|
||||||
|
:cancel-text="$t('status.delete_confirm_cancel_button')"
|
||||||
|
:confirm-text="$t('status.delete_confirm_accept_button')"
|
||||||
|
@cancelled="hideDeleteStatusConfirmDialog"
|
||||||
|
@accepted="doDeleteStatus"
|
||||||
|
>
|
||||||
|
{{ $t('status.delete_confirm') }}
|
||||||
|
</ConfirmModal>
|
||||||
|
</teleport>
|
||||||
</template>
|
</template>
|
||||||
</Popover>
|
</Popover>
|
||||||
</template>
|
</template>
|
||||||
|
@ -151,4 +207,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 801px) {
|
||||||
|
.extra-quote {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
.FavoriteButton {
|
.FavoriteButton {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
margin-right: 5px;
|
||||||
|
|
||||||
> :first-child {
|
> :first-child {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
|
import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
|
||||||
export default {
|
export default {
|
||||||
props: ['relationship', 'user', 'labelFollowing', 'buttonClass'],
|
props: ['relationship', 'user', 'labelFollowing', 'buttonClass'],
|
||||||
|
components: {
|
||||||
|
ConfirmModal
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
inProgress: false
|
inProgress: false,
|
||||||
|
showingConfirmUnfollow: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
shouldConfirmUnfollow () {
|
||||||
|
return this.$store.getters.mergedConfig.modalOnUnfollow
|
||||||
|
},
|
||||||
isPressed () {
|
isPressed () {
|
||||||
return this.inProgress || this.relationship.following
|
return this.inProgress || this.relationship.following
|
||||||
},
|
},
|
||||||
|
@ -35,6 +43,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showConfirmUnfollow () {
|
||||||
|
this.showingConfirmUnfollow = true
|
||||||
|
},
|
||||||
|
hideConfirmUnfollow () {
|
||||||
|
this.showingConfirmUnfollow = false
|
||||||
|
},
|
||||||
onClick () {
|
onClick () {
|
||||||
this.relationship.following || this.relationship.requested ? this.unfollow() : this.follow()
|
this.relationship.following || this.relationship.requested ? this.unfollow() : this.follow()
|
||||||
},
|
},
|
||||||
|
@ -45,12 +59,21 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
unfollow () {
|
unfollow () {
|
||||||
|
if (this.shouldConfirmUnfollow) {
|
||||||
|
this.showConfirmUnfollow()
|
||||||
|
} else {
|
||||||
|
this.doUnfollow()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doUnfollow () {
|
||||||
const store = this.$store
|
const store = this.$store
|
||||||
this.inProgress = true
|
this.inProgress = true
|
||||||
requestUnfollow(this.relationship.id, store).then(() => {
|
requestUnfollow(this.relationship.id, store).then(() => {
|
||||||
this.inProgress = false
|
this.inProgress = false
|
||||||
store.commit('removeStatus', { timeline: 'friends', userId: this.relationship.id })
|
store.commit('removeStatus', { timeline: 'friends', userId: this.relationship.id })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.hideConfirmUnfollow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,27 @@
|
||||||
@click="onClick"
|
@click="onClick"
|
||||||
>
|
>
|
||||||
{{ label }}
|
{{ label }}
|
||||||
|
<teleport to="#modal">
|
||||||
|
<confirm-modal
|
||||||
|
v-if="showingConfirmUnfollow"
|
||||||
|
:title="$t('user_card.unfollow_confirm_title')"
|
||||||
|
:confirm-text="$t('user_card.unfollow_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('user_card.unfollow_confirm_cancel_button')"
|
||||||
|
@accepted="doUnfollow"
|
||||||
|
@cancelled="hideConfirmUnfollow"
|
||||||
|
>
|
||||||
|
<i18n-t
|
||||||
|
keypath="user_card.unfollow_confirm"
|
||||||
|
tag="span"
|
||||||
|
>
|
||||||
|
<template #user>
|
||||||
|
<span
|
||||||
|
v-text="user.screen_name_ui"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
</confirm-modal>
|
||||||
|
</teleport>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
||||||
import RemoteFollow from '../remote_follow/remote_follow.vue'
|
import RemoteFollow from '../remote_follow/remote_follow.vue'
|
||||||
import FollowButton from '../follow_button/follow_button.vue'
|
import FollowButton from '../follow_button/follow_button.vue'
|
||||||
|
import RemoveFollowerButton from '../remove_follower_button/remove_follower_button.vue'
|
||||||
|
|
||||||
const FollowCard = {
|
const FollowCard = {
|
||||||
props: [
|
props: [
|
||||||
|
@ -10,7 +11,8 @@ const FollowCard = {
|
||||||
components: {
|
components: {
|
||||||
BasicUserCard,
|
BasicUserCard,
|
||||||
RemoteFollow,
|
RemoteFollow,
|
||||||
FollowButton
|
FollowButton,
|
||||||
|
RemoveFollowerButton
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isMe () {
|
isMe () {
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
class="follow-card-follow-button"
|
class="follow-card-follow-button"
|
||||||
:user="user"
|
:user="user"
|
||||||
/>
|
/>
|
||||||
|
<RemoveFollowerButton
|
||||||
|
v-if="noFollowsYou && relationship.followed_by"
|
||||||
|
:relationship="relationship"
|
||||||
|
class="follow-card-button"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</basic-user-card>
|
</basic-user-card>
|
||||||
|
@ -40,6 +45,12 @@
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-button {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
padding: 0 1.5em;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
&-follow-button {
|
&-follow-button {
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
||||||
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { notificationsFromStore } from '../../services/notification_utils/notification_utils.js'
|
import { notificationsFromStore } from '../../services/notification_utils/notification_utils.js'
|
||||||
|
|
||||||
const FollowRequestCard = {
|
const FollowRequestCard = {
|
||||||
props: ['user'],
|
props: ['user'],
|
||||||
components: {
|
components: {
|
||||||
BasicUserCard
|
BasicUserCard,
|
||||||
|
ConfirmModal
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
showingApproveConfirmDialog: false,
|
||||||
|
showingDenyConfirmDialog: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
findFollowRequestNotificationId () {
|
findFollowRequestNotificationId () {
|
||||||
|
@ -13,7 +21,26 @@ const FollowRequestCard = {
|
||||||
)
|
)
|
||||||
return notif && notif.id
|
return notif && notif.id
|
||||||
},
|
},
|
||||||
|
showApproveConfirmDialog () {
|
||||||
|
this.showingApproveConfirmDialog = true
|
||||||
|
},
|
||||||
|
hideApproveConfirmDialog () {
|
||||||
|
this.showingApproveConfirmDialog = false
|
||||||
|
},
|
||||||
|
showDenyConfirmDialog () {
|
||||||
|
this.showingDenyConfirmDialog = true
|
||||||
|
},
|
||||||
|
hideDenyConfirmDialog () {
|
||||||
|
this.showingDenyConfirmDialog = false
|
||||||
|
},
|
||||||
approveUser () {
|
approveUser () {
|
||||||
|
if (this.shouldConfirmApprove) {
|
||||||
|
this.showApproveConfirmDialog()
|
||||||
|
} else {
|
||||||
|
this.doApprove()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doApprove () {
|
||||||
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
|
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
|
||||||
this.$store.dispatch('removeFollowRequest', this.user)
|
this.$store.dispatch('removeFollowRequest', this.user)
|
||||||
|
|
||||||
|
@ -25,14 +52,34 @@ const FollowRequestCard = {
|
||||||
notification.type = 'follow'
|
notification.type = 'follow'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
this.hideApproveConfirmDialog()
|
||||||
},
|
},
|
||||||
denyUser () {
|
denyUser () {
|
||||||
|
if (this.shouldConfirmDeny) {
|
||||||
|
this.showDenyConfirmDialog()
|
||||||
|
} else {
|
||||||
|
this.doDeny()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doDeny () {
|
||||||
const notifId = this.findFollowRequestNotificationId()
|
const notifId = this.findFollowRequestNotificationId()
|
||||||
this.$store.state.api.backendInteractor.denyUser({ id: this.user.id })
|
this.$store.state.api.backendInteractor.denyUser({ id: this.user.id })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$store.dispatch('dismissNotificationLocal', { id: notifId })
|
this.$store.dispatch('dismissNotificationLocal', { id: notifId })
|
||||||
this.$store.dispatch('removeFollowRequest', this.user)
|
this.$store.dispatch('removeFollowRequest', this.user)
|
||||||
})
|
})
|
||||||
|
this.hideDenyConfirmDialog()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
mergedConfig () {
|
||||||
|
return this.$store.getters.mergedConfig
|
||||||
|
},
|
||||||
|
shouldConfirmApprove () {
|
||||||
|
return this.mergedConfig.modalOnApproveFollow
|
||||||
|
},
|
||||||
|
shouldConfirmDeny () {
|
||||||
|
return this.mergedConfig.modalOnDenyFollow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,28 @@
|
||||||
{{ $t('user_card.deny') }}
|
{{ $t('user_card.deny') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<teleport to="#modal">
|
||||||
|
<confirm-modal
|
||||||
|
v-if="showingApproveConfirmDialog"
|
||||||
|
:title="$t('user_card.approve_confirm_title')"
|
||||||
|
:confirm-text="$t('user_card.approve_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('user_card.approve_confirm_cancel_button')"
|
||||||
|
@accepted="doApprove"
|
||||||
|
@cancelled="hideApproveConfirmDialog"
|
||||||
|
>
|
||||||
|
{{ $t('user_card.approve_confirm', { user: user.screen_name_ui }) }}
|
||||||
|
</confirm-modal>
|
||||||
|
<confirm-modal
|
||||||
|
v-if="showingDenyConfirmDialog"
|
||||||
|
:title="$t('user_card.deny_confirm_title')"
|
||||||
|
:confirm-text="$t('user_card.deny_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('user_card.deny_confirm_cancel_button')"
|
||||||
|
@accepted="doDeny"
|
||||||
|
@cancelled="hideDenyConfirmDialog"
|
||||||
|
>
|
||||||
|
{{ $t('user_card.deny_confirm', { user: user.screen_name_ui }) }}
|
||||||
|
</confirm-modal>
|
||||||
|
</teleport>
|
||||||
</basic-user-card>
|
</basic-user-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<FAIcon
|
||||||
|
v-if="globeIcon"
|
||||||
|
icon="globe"
|
||||||
|
/>
|
||||||
|
{{ ' ' }}
|
||||||
<label for="interface-language-switcher">
|
<label for="interface-language-switcher">
|
||||||
{{ promptText }}
|
{{ promptText }}
|
||||||
</label>
|
</label>
|
||||||
|
@ -39,6 +44,10 @@ export default {
|
||||||
setLanguage: {
|
setLanguage: {
|
||||||
type: Function,
|
type: Function,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
globeIcon: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -188,9 +188,21 @@ $modal-view-button-icon-margin: 0.5em;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
min-height: 1em;
|
min-height: 1em;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
max-height: 9.5em;
|
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
|
background: rgba(0,0,0,0.6);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
transition: 0.5s;
|
||||||
|
|
||||||
|
&:not(:hover) {
|
||||||
|
max-height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
max-height: 9.5em;
|
||||||
|
transition: 1s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-image {
|
.modal-image {
|
||||||
|
|
|
@ -15,11 +15,15 @@
|
||||||
|
|
||||||
.mention-avatar {
|
.mention-avatar {
|
||||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||||
width: 1.5em;
|
width: 2em;
|
||||||
height: 1.5em;
|
height: 2em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
margin-right: 0.2em;
|
margin-right: 0.2em;
|
||||||
|
|
||||||
|
.still-image.avatar {
|
||||||
|
border-radius: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.full {
|
.full {
|
||||||
|
@ -113,3 +117,11 @@
|
||||||
color: var(--faint, $fallback--faint);
|
color: var(--faint, $fallback--faint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reply-glued-label {
|
||||||
|
|
||||||
|
.mention-avatar {
|
||||||
|
width: 1.4em;
|
||||||
|
height: 1.4em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
@click.prevent="onClick"
|
@click.prevent="onClick"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
|
<UserAvatar
|
||||||
|
v-if="shouldShowAvatar"
|
||||||
|
class="mention-avatar"
|
||||||
|
:user="user"
|
||||||
|
/>
|
||||||
<span class="shortName">@<span
|
<span class="shortName">@<span
|
||||||
class="userName"
|
class="userName"
|
||||||
v-html="userName"
|
v-html="userName"
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import SideDrawer from '../side_drawer/side_drawer.vue'
|
import SideDrawer from '../side_drawer/side_drawer.vue'
|
||||||
import Notifications from '../notifications/notifications.vue'
|
import Notifications from '../notifications/notifications.vue'
|
||||||
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils'
|
import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils'
|
||||||
import GestureService from '../../services/gesture_service/gesture_service'
|
import GestureService from '../../services/gesture_service/gesture_service'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faTimes,
|
faTimes,
|
||||||
|
@ -18,11 +20,13 @@ library.add(
|
||||||
const MobileNav = {
|
const MobileNav = {
|
||||||
components: {
|
components: {
|
||||||
SideDrawer,
|
SideDrawer,
|
||||||
Notifications
|
Notifications,
|
||||||
|
ConfirmModal
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
notificationsCloseGesture: undefined,
|
notificationsCloseGesture: undefined,
|
||||||
notificationsOpen: false
|
notificationsOpen: false,
|
||||||
|
showingConfirmLogout: false
|
||||||
}),
|
}),
|
||||||
created () {
|
created () {
|
||||||
this.notificationsCloseGesture = GestureService.swipeGesture(
|
this.notificationsCloseGesture = GestureService.swipeGesture(
|
||||||
|
@ -41,8 +45,17 @@ const MobileNav = {
|
||||||
unseenNotificationsCount () {
|
unseenNotificationsCount () {
|
||||||
return this.unseenNotifications.length
|
return this.unseenNotifications.length
|
||||||
},
|
},
|
||||||
hideSitename () { return this.$store.state.instance.hideSitename },
|
mergedConfig () {
|
||||||
sitename () { return this.$store.state.instance.name }
|
return this.$store.getters.mergedConfig
|
||||||
|
},
|
||||||
|
hideSiteName () {
|
||||||
|
return this.mergedConfig.hideSiteName
|
||||||
|
},
|
||||||
|
sitename () { return this.$store.state.instance.name },
|
||||||
|
shouldConfirmLogout () {
|
||||||
|
return this.$store.getters.mergedConfig.modalOnLogout
|
||||||
|
},
|
||||||
|
...mapGetters(['unreadChatCount'])
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleMobileSidebar () {
|
toggleMobileSidebar () {
|
||||||
|
@ -68,9 +81,23 @@ const MobileNav = {
|
||||||
scrollToTop () {
|
scrollToTop () {
|
||||||
window.scrollTo(0, 0)
|
window.scrollTo(0, 0)
|
||||||
},
|
},
|
||||||
|
showConfirmLogout () {
|
||||||
|
this.showingConfirmLogout = true
|
||||||
|
},
|
||||||
|
hideConfirmLogout () {
|
||||||
|
this.showingConfirmLogout = false
|
||||||
|
},
|
||||||
logout () {
|
logout () {
|
||||||
|
if (!this.shouldConfirmLogout) {
|
||||||
|
this.doLogout()
|
||||||
|
} else {
|
||||||
|
this.showConfirmLogout()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doLogout () {
|
||||||
this.$router.replace('/main/public')
|
this.$router.replace('/main/public')
|
||||||
this.$store.dispatch('logout')
|
this.$store.dispatch('logout')
|
||||||
|
this.hideConfirmLogout()
|
||||||
},
|
},
|
||||||
markNotificationsAsSeen () {
|
markNotificationsAsSeen () {
|
||||||
// this.$refs.notifications.markAsSeen()
|
// this.$refs.notifications.markAsSeen()
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="!hideSitename"
|
v-if="!hideSiteName"
|
||||||
class="site-name"
|
class="site-name"
|
||||||
:to="{ name: 'root' }"
|
:to="{ name: 'root' }"
|
||||||
active-class="home"
|
active-class="home"
|
||||||
|
@ -76,6 +76,18 @@
|
||||||
ref="sideDrawer"
|
ref="sideDrawer"
|
||||||
:logout="logout"
|
:logout="logout"
|
||||||
/>
|
/>
|
||||||
|
<teleport to="#modal">
|
||||||
|
<confirm-modal
|
||||||
|
v-if="showingConfirmLogout"
|
||||||
|
:title="$t('login.logout_confirm_title')"
|
||||||
|
:confirm-text="$t('login.logout_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('login.logout_confirm_cancel_button')"
|
||||||
|
@accepted="doLogout"
|
||||||
|
@cancelled="hideConfirmLogout"
|
||||||
|
>
|
||||||
|
{{ $t('login.logout_confirm') }}
|
||||||
|
</confirm-modal>
|
||||||
|
</teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -206,6 +218,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.confirm-modal.dark-overlay {
|
||||||
|
&::before {
|
||||||
|
z-index: 3000;
|
||||||
|
}
|
||||||
|
.dialog-modal.panel {
|
||||||
|
z-index: 3001;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-if="federationPolicy"
|
v-if="hasInstanceSpecificPolicies"
|
||||||
class="mrf-transparency-panel"
|
class="mrf-transparency-panel"
|
||||||
>
|
>
|
||||||
<div class="panel panel-default base01-background">
|
<div class="panel panel-default base01-background">
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="quarantineInstances.length">
|
<!--<div v-if="quarantineInstances.length">
|
||||||
<h4>{{ $t("about.mrf.simple.quarantine") }}</h4>
|
<h4>{{ $t("about.mrf.simple.quarantine") }}</h4>
|
||||||
|
|
||||||
<p>{{ $t("about.mrf.simple.quarantine_desc") }}</p>
|
<p>{{ $t("about.mrf.simple.quarantine_desc") }}</p>
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>-->
|
||||||
|
|
||||||
<div v-if="ftlRemovalInstances.length">
|
<div v-if="ftlRemovalInstances.length">
|
||||||
<h4>{{ $t("about.mrf.simple.ftl_removal") }}</h4>
|
<h4>{{ $t("about.mrf.simple.ftl_removal") }}</h4>
|
||||||
|
@ -176,7 +176,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 v-if="hasKeywordPolicies">
|
<!--<h2 v-if="hasKeywordPolicies">
|
||||||
{{ $t("about.mrf.keyword.keyword_policies") }}
|
{{ $t("about.mrf.keyword.keyword_policies") }}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@
|
||||||
{{ keyword.replacement }}
|
{{ keyword.replacement }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
faChevronUp,
|
faChevronUp,
|
||||||
faComments,
|
faComments,
|
||||||
faBell,
|
faBolt,
|
||||||
faInfoCircle,
|
faInfoCircle,
|
||||||
faStream,
|
faStream,
|
||||||
faList,
|
faList,
|
||||||
|
@ -25,7 +25,7 @@ library.add(
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
faChevronUp,
|
faChevronUp,
|
||||||
faComments,
|
faComments,
|
||||||
faBell,
|
faBolt,
|
||||||
faInfoCircle,
|
faInfoCircle,
|
||||||
faStream,
|
faStream,
|
||||||
faList,
|
faList,
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
class="fa-scale-110"
|
class="fa-scale-110"
|
||||||
icon="bell"
|
icon="bolt"
|
||||||
/>{{ $t("nav.interactions") }}
|
/>{{ $t("nav.interactions") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||||
import UserCard from '../user_card/user_card.vue'
|
import UserCard from '../user_card/user_card.vue'
|
||||||
import Timeago from '../timeago/timeago.vue'
|
import Timeago from '../timeago/timeago.vue'
|
||||||
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||||
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
|
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
|
||||||
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
|
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.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'
|
||||||
|
@ -36,7 +37,9 @@ const Notification = {
|
||||||
return {
|
return {
|
||||||
userExpanded: false,
|
userExpanded: false,
|
||||||
betterShadow: this.$store.state.interface.browserSupport.cssFilter,
|
betterShadow: this.$store.state.interface.browserSupport.cssFilter,
|
||||||
unmuted: false
|
unmuted: false,
|
||||||
|
showingApproveConfirmDialog: false,
|
||||||
|
showingDenyConfirmDialog: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: [ 'notification' ],
|
props: [ 'notification' ],
|
||||||
|
@ -46,7 +49,8 @@ const Notification = {
|
||||||
UserCard,
|
UserCard,
|
||||||
Timeago,
|
Timeago,
|
||||||
Status,
|
Status,
|
||||||
RichContent
|
RichContent,
|
||||||
|
ConfirmModal
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleUserExpanded () {
|
toggleUserExpanded () {
|
||||||
|
@ -61,7 +65,26 @@ const Notification = {
|
||||||
toggleMute () {
|
toggleMute () {
|
||||||
this.unmuted = !this.unmuted
|
this.unmuted = !this.unmuted
|
||||||
},
|
},
|
||||||
|
showApproveConfirmDialog () {
|
||||||
|
this.showingApproveConfirmDialog = true
|
||||||
|
},
|
||||||
|
hideApproveConfirmDialog () {
|
||||||
|
this.showingApproveConfirmDialog = false
|
||||||
|
},
|
||||||
|
showDenyConfirmDialog () {
|
||||||
|
this.showingDenyConfirmDialog = true
|
||||||
|
},
|
||||||
|
hideDenyConfirmDialog () {
|
||||||
|
this.showingDenyConfirmDialog = false
|
||||||
|
},
|
||||||
approveUser () {
|
approveUser () {
|
||||||
|
if (this.shouldConfirmApprove) {
|
||||||
|
this.showApproveConfirmDialog()
|
||||||
|
} else {
|
||||||
|
this.doApprove()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doApprove () {
|
||||||
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
|
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
|
||||||
this.$store.dispatch('removeFollowRequest', this.user)
|
this.$store.dispatch('removeFollowRequest', this.user)
|
||||||
this.$store.dispatch('markSingleNotificationAsSeen', { id: this.notification.id })
|
this.$store.dispatch('markSingleNotificationAsSeen', { id: this.notification.id })
|
||||||
|
@ -71,13 +94,22 @@ const Notification = {
|
||||||
notification.type = 'follow'
|
notification.type = 'follow'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
this.hideApproveConfirmDialog()
|
||||||
},
|
},
|
||||||
denyUser () {
|
denyUser () {
|
||||||
|
if (this.shouldConfirmDeny) {
|
||||||
|
this.showDenyConfirmDialog()
|
||||||
|
} else {
|
||||||
|
this.doDeny()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doDeny () {
|
||||||
this.$store.state.api.backendInteractor.denyUser({ id: this.user.id })
|
this.$store.state.api.backendInteractor.denyUser({ id: this.user.id })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$store.dispatch('dismissNotificationLocal', { id: this.notification.id })
|
this.$store.dispatch('dismissNotificationLocal', { id: this.notification.id })
|
||||||
this.$store.dispatch('removeFollowRequest', this.user)
|
this.$store.dispatch('removeFollowRequest', this.user)
|
||||||
})
|
})
|
||||||
|
this.hideDenyConfirmDialog()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -107,6 +139,15 @@ const Notification = {
|
||||||
isStatusNotification () {
|
isStatusNotification () {
|
||||||
return isStatusNotification(this.notification.type)
|
return isStatusNotification(this.notification.type)
|
||||||
},
|
},
|
||||||
|
mergedConfig () {
|
||||||
|
return this.$store.getters.mergedConfig
|
||||||
|
},
|
||||||
|
shouldConfirmApprove () {
|
||||||
|
return this.mergedConfig.modalOnApproveFollow
|
||||||
|
},
|
||||||
|
shouldConfirmDeny () {
|
||||||
|
return this.mergedConfig.modalOnDenyFollow
|
||||||
|
},
|
||||||
...mapState({
|
...mapState({
|
||||||
currentUser: state => state.users.currentUser
|
currentUser: state => state.users.currentUser
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
@import '../../_variables.scss';
|
@import '../../_variables.scss';
|
||||||
|
|
||||||
.notification-reaction-emoji {
|
.notification-reaction-emoji {
|
||||||
width: 40px;
|
width: 32px;
|
||||||
display: flex;
|
display: inline-flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Copypaste from Status, should unify it somehow
|
// TODO Copypaste from Status, should unify it somehow
|
||||||
|
|
|
@ -151,6 +151,7 @@
|
||||||
>
|
>
|
||||||
<Timeago
|
<Timeago
|
||||||
:time="notification.created_at"
|
:time="notification.created_at"
|
||||||
|
:with-direction="true"
|
||||||
:auto-update="240"
|
:auto-update="240"
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -230,6 +231,28 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<teleport to="#modal">
|
||||||
|
<confirm-modal
|
||||||
|
v-if="showingApproveConfirmDialog"
|
||||||
|
:title="$t('user_card.approve_confirm_title')"
|
||||||
|
:confirm-text="$t('user_card.approve_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('user_card.approve_confirm_cancel_button')"
|
||||||
|
@accepted="doApprove"
|
||||||
|
@cancelled="hideApproveConfirmDialog"
|
||||||
|
>
|
||||||
|
{{ $t('user_card.approve_confirm', { user: user.screen_name_ui }) }}
|
||||||
|
</confirm-modal>
|
||||||
|
<confirm-modal
|
||||||
|
v-if="showingDenyConfirmDialog"
|
||||||
|
:title="$t('user_card.deny_confirm_title')"
|
||||||
|
:confirm-text="$t('user_card.deny_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('user_card.deny_confirm_cancel_button')"
|
||||||
|
@accepted="doDeny"
|
||||||
|
@cancelled="hideDenyConfirmDialog"
|
||||||
|
>
|
||||||
|
{{ $t('user_card.deny_confirm', { user: user.screen_name_ui }) }}
|
||||||
|
</confirm-modal>
|
||||||
|
</teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
:key="unit"
|
:key="unit"
|
||||||
:value="unit"
|
:value="unit"
|
||||||
>
|
>
|
||||||
{{ $t(`time.unit.${unit}_short`, ['']) }}
|
{{ $tc(`time.unit.${unit}_short`, expiryAmount, ['']) }}
|
||||||
</option>
|
</option>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -55,6 +55,14 @@ const pxStringToNumber = (str) => {
|
||||||
|
|
||||||
const PostStatusForm = {
|
const PostStatusForm = {
|
||||||
props: [
|
props: [
|
||||||
|
'statusId',
|
||||||
|
'statusText',
|
||||||
|
'statusIsSensitive',
|
||||||
|
'statusPoll',
|
||||||
|
'statusFiles',
|
||||||
|
'statusMediaDescriptions',
|
||||||
|
'statusScope',
|
||||||
|
'statusContentType',
|
||||||
'replyTo',
|
'replyTo',
|
||||||
'quoteId',
|
'quoteId',
|
||||||
'repliedUser',
|
'repliedUser',
|
||||||
|
@ -63,6 +71,7 @@ const PostStatusForm = {
|
||||||
'subject',
|
'subject',
|
||||||
'disableSubject',
|
'disableSubject',
|
||||||
'disableScopeSelector',
|
'disableScopeSelector',
|
||||||
|
'disableVisibilitySelector',
|
||||||
'disableNotice',
|
'disableNotice',
|
||||||
'disableLockWarning',
|
'disableLockWarning',
|
||||||
'disablePolls',
|
'disablePolls',
|
||||||
|
@ -120,23 +129,40 @@ const PostStatusForm = {
|
||||||
|
|
||||||
const { postContentType: contentType, sensitiveByDefault, sensitiveIfSubject } = this.$store.getters.mergedConfig
|
const { postContentType: contentType, sensitiveByDefault, sensitiveIfSubject } = this.$store.getters.mergedConfig
|
||||||
|
|
||||||
return {
|
let statusParams = {
|
||||||
dropFiles: [],
|
|
||||||
uploadingFiles: false,
|
|
||||||
error: null,
|
|
||||||
posting: false,
|
|
||||||
highlighted: 0,
|
|
||||||
newStatus: {
|
|
||||||
spoilerText: this.subject || '',
|
spoilerText: this.subject || '',
|
||||||
status: statusText,
|
status: statusText,
|
||||||
sensitiveIfSubject,
|
sensitiveByDefault,
|
||||||
nsfw: !!sensitiveByDefault,
|
nsfw: !!sensitiveByDefault,
|
||||||
files: [],
|
files: [],
|
||||||
poll: {},
|
poll: {},
|
||||||
mediaDescriptions: {},
|
mediaDescriptions: {},
|
||||||
visibility: this.suggestedVisibility(),
|
visibility: this.suggestedVisibility(),
|
||||||
contentType
|
contentType
|
||||||
},
|
}
|
||||||
|
|
||||||
|
if (this.statusId) {
|
||||||
|
const statusContentType = this.statusContentType || contentType
|
||||||
|
statusParams = {
|
||||||
|
spoilerText: this.subject || '',
|
||||||
|
status: this.statusText || '',
|
||||||
|
sensitiveIfSubject,
|
||||||
|
nsfw: this.statusIsSensitive || !!sensitiveByDefault,
|
||||||
|
files: this.statusFiles || [],
|
||||||
|
poll: this.statusPoll || {},
|
||||||
|
mediaDescriptions: this.statusMediaDescriptions || {},
|
||||||
|
visibility: this.statusScope || this.suggestedVisibility(),
|
||||||
|
contentType: statusContentType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
dropFiles: [],
|
||||||
|
uploadingFiles: false,
|
||||||
|
error: null,
|
||||||
|
posting: false,
|
||||||
|
highlighted: 0,
|
||||||
|
newStatus: statusParams,
|
||||||
caret: 0,
|
caret: 0,
|
||||||
pollFormVisible: false,
|
pollFormVisible: false,
|
||||||
showDropIcon: 'hide',
|
showDropIcon: 'hide',
|
||||||
|
@ -232,6 +258,9 @@ const PostStatusForm = {
|
||||||
uploadFileLimitReached () {
|
uploadFileLimitReached () {
|
||||||
return this.newStatus.files.length >= this.fileLimit
|
return this.newStatus.files.length >= this.fileLimit
|
||||||
},
|
},
|
||||||
|
isEdit () {
|
||||||
|
return typeof this.statusId !== 'undefined' && this.statusId.trim() !== ''
|
||||||
|
},
|
||||||
...mapGetters(['mergedConfig']),
|
...mapGetters(['mergedConfig']),
|
||||||
...mapState({
|
...mapState({
|
||||||
mobileLayout: state => state.interface.mobileLayout
|
mobileLayout: state => state.interface.mobileLayout
|
||||||
|
|
|
@ -66,6 +66,13 @@
|
||||||
<span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
|
<span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
|
||||||
<span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
|
<span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
|
||||||
</p>
|
</p>
|
||||||
|
<div
|
||||||
|
v-if="isEdit"
|
||||||
|
class="visibility-notice edit-warning"
|
||||||
|
>
|
||||||
|
<p>{{ $t('post_status.edit_remote_warning') }}</p>
|
||||||
|
<p>{{ $t('post_status.edit_unsupported_warning') }}</p>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="!disablePreview"
|
v-if="!disablePreview"
|
||||||
class="preview-heading faint"
|
class="preview-heading faint"
|
||||||
|
@ -180,6 +187,7 @@
|
||||||
class="visibility-tray"
|
class="visibility-tray"
|
||||||
>
|
>
|
||||||
<scope-selector
|
<scope-selector
|
||||||
|
v-if="!disableVisibilitySelector"
|
||||||
:show-all="showAllScopes"
|
:show-all="showAllScopes"
|
||||||
:user-default="userDefaultScope"
|
:user-default="userDefaultScope"
|
||||||
:original-scope="copyMessageScope"
|
:original-scope="copyMessageScope"
|
||||||
|
@ -420,6 +428,16 @@
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.visibility-notice.edit-warning {
|
||||||
|
> :first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> :last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.media-upload-icon, .poll-icon, .emoji-icon {
|
.media-upload-icon, .poll-icon, .emoji-icon {
|
||||||
font-size: 1.85em;
|
font-size: 1.85em;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
.QuoteButton {
|
.QuoteButton {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
margin-left: -5px;
|
||||||
|
|
||||||
> :first-child {
|
> :first-child {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
@ -44,4 +45,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media all and (max-width: 800px) {
|
||||||
|
.QuoteButton {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -64,11 +64,11 @@
|
||||||
|
|
||||||
color: $fallback--text;
|
color: $fallback--text;
|
||||||
color: var(--text, $fallback--text);
|
color: var(--text, $fallback--text);
|
||||||
border-style: solid;
|
border-style: dashed;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-radius: $fallback--attachmentRadius;
|
border-radius: $fallback--attachmentRadius;
|
||||||
border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
|
border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
|
||||||
border-color: $fallback--border;
|
border-color: $fallback--cBlue;
|
||||||
border-color: var(--border, $fallback--border);
|
border-color: var(--cBlue, $fallback--cBlue);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
export default {
|
||||||
|
props: ['relationship'],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
inProgress: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
label () {
|
||||||
|
if (this.inProgress) {
|
||||||
|
return this.$t('user_card.follow_progress')
|
||||||
|
} else {
|
||||||
|
return this.$t('user_card.remove_follower')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick () {
|
||||||
|
this.inProgress = true
|
||||||
|
this.$store.dispatch('removeUserFromFollowers', this.relationship.id).then(() => {
|
||||||
|
this.inProgress = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<template>
|
||||||
|
<button
|
||||||
|
class="btn button-default follow-button"
|
||||||
|
:class="{ toggled: inProgress }"
|
||||||
|
:disabled="inProgress"
|
||||||
|
:title="$t('user_card.remove_follower')"
|
||||||
|
@click="onClick"
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./remove_follower_button.js"></script>
|
|
@ -1,3 +1,4 @@
|
||||||
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faRetweet } from '@fortawesome/free-solid-svg-icons'
|
import { faRetweet } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
@ -5,13 +6,24 @@ library.add(faRetweet)
|
||||||
|
|
||||||
const RetweetButton = {
|
const RetweetButton = {
|
||||||
props: ['status', 'loggedIn', 'visibility'],
|
props: ['status', 'loggedIn', 'visibility'],
|
||||||
|
components: {
|
||||||
|
ConfirmModal
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
animated: false
|
animated: false,
|
||||||
|
showingConfirmDialog: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
retweet () {
|
retweet () {
|
||||||
|
if (!this.status.repeated && this.shouldConfirmRepeat) {
|
||||||
|
this.showConfirmDialog()
|
||||||
|
} else {
|
||||||
|
this.doRetweet()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doRetweet () {
|
||||||
if (!this.status.repeated) {
|
if (!this.status.repeated) {
|
||||||
this.$store.dispatch('retweet', { id: this.status.id })
|
this.$store.dispatch('retweet', { id: this.status.id })
|
||||||
} else {
|
} else {
|
||||||
|
@ -21,6 +33,13 @@ const RetweetButton = {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.animated = false
|
this.animated = false
|
||||||
}, 500)
|
}, 500)
|
||||||
|
this.hideConfirmDialog()
|
||||||
|
},
|
||||||
|
showConfirmDialog () {
|
||||||
|
this.showingConfirmDialog = true
|
||||||
|
},
|
||||||
|
hideConfirmDialog () {
|
||||||
|
this.showingConfirmDialog = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -29,6 +48,9 @@ const RetweetButton = {
|
||||||
},
|
},
|
||||||
mergedConfig () {
|
mergedConfig () {
|
||||||
return this.$store.getters.mergedConfig
|
return this.$store.getters.mergedConfig
|
||||||
|
},
|
||||||
|
shouldConfirmRepeat () {
|
||||||
|
return this.mergedConfig.modalOnRepeat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,18 @@
|
||||||
>
|
>
|
||||||
{{ status.repeat_num }}
|
{{ status.repeat_num }}
|
||||||
</span>
|
</span>
|
||||||
|
<teleport to="#modal">
|
||||||
|
<confirm-modal
|
||||||
|
v-if="showingConfirmDialog"
|
||||||
|
:title="$t('status.repeat_confirm_title')"
|
||||||
|
:confirm-text="$t('status.repeat_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('status.repeat_confirm_cancel_button')"
|
||||||
|
@accepted="doRetweet"
|
||||||
|
@cancelled="hideConfirmDialog"
|
||||||
|
>
|
||||||
|
{{ $t('status.repeat_confirm') }}
|
||||||
|
</confirm-modal>
|
||||||
|
</teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,14 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderMisskeyMarkdown = (content) => {
|
const renderMisskeyMarkdown = (content) => {
|
||||||
|
// Untangle code blocks from <br> tags
|
||||||
|
const codeblocks = content.match(/(<br\/>)?(~~~|```)\w*<br\/>.+?<br\/>\2\1?/g)
|
||||||
|
if (codeblocks) {
|
||||||
|
codeblocks.forEach((pre) => {
|
||||||
|
content = content.replace(pre, pre.replaceAll('<br/>', '\n'))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
marked.use(markedMfm, {
|
marked.use(markedMfm, {
|
||||||
mangle: false,
|
mangle: false,
|
||||||
gfm: false,
|
gfm: false,
|
||||||
|
@ -133,6 +141,7 @@ export default {
|
||||||
mfmHtml.innerHTML = marked.parse(content)
|
mfmHtml.innerHTML = marked.parse(content)
|
||||||
|
|
||||||
// Add options with set values to CSS
|
// Add options with set values to CSS
|
||||||
|
if (mfmHtml.content.firstChild) {
|
||||||
Array.from(mfmHtml.content.firstChild.getElementsByClassName('mfm')).map((el) => {
|
Array.from(mfmHtml.content.firstChild.getElementsByClassName('mfm')).map((el) => {
|
||||||
if (el.dataset.speed) {
|
if (el.dataset.speed) {
|
||||||
el.style.animationDuration = el.dataset.speed
|
el.style.animationDuration = el.dataset.speed
|
||||||
|
@ -147,6 +156,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return mfmHtml.innerHTML
|
return mfmHtml.innerHTML
|
||||||
}
|
}
|
||||||
|
@ -359,8 +369,6 @@ export const preProcessPerLine = (html, greentext) => {
|
||||||
.trim()
|
.trim()
|
||||||
if (cleanedString.startsWith('>')) {
|
if (cleanedString.startsWith('>')) {
|
||||||
return `<span class='greentext'>${string}</span>`
|
return `<span class='greentext'>${string}</span>`
|
||||||
} else if (cleanedString.startsWith('<')) {
|
|
||||||
return `<span class='cyantext'>${string}</span>`
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faLock,
|
faLock,
|
||||||
|
faBiohazard,
|
||||||
faLockOpen,
|
faLockOpen,
|
||||||
faGlobe
|
faGlobe
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
@ -9,6 +10,7 @@ import {
|
||||||
library.add(
|
library.add(
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
|
faBiohazard,
|
||||||
faLock,
|
faLock,
|
||||||
faLockOpen
|
faLockOpen
|
||||||
)
|
)
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
@click="changeVis('local')"
|
@click="changeVis('local')"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
icon="users"
|
icon="biohazard"
|
||||||
class="fa-scale-110 fa-old-padding"
|
class="fa-scale-110 fa-old-padding"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
faTimes,
|
faTimes,
|
||||||
faFileUpload,
|
faFileUpload,
|
||||||
faFileDownload,
|
faFileDownload,
|
||||||
|
faSignOutAlt,
|
||||||
faChevronDown
|
faChevronDown
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import {
|
import {
|
||||||
|
@ -28,6 +29,7 @@ library.add(
|
||||||
faWindowMinimize,
|
faWindowMinimize,
|
||||||
faFileUpload,
|
faFileUpload,
|
||||||
faFileDownload,
|
faFileDownload,
|
||||||
|
faSignOutAlt,
|
||||||
faChevronDown
|
faChevronDown
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -66,6 +68,11 @@ const SettingsModal = {
|
||||||
closeModal () {
|
closeModal () {
|
||||||
this.$store.dispatch('closeSettingsModal')
|
this.$store.dispatch('closeSettingsModal')
|
||||||
},
|
},
|
||||||
|
logout () {
|
||||||
|
this.$router.replace('/main/public')
|
||||||
|
this.$store.dispatch('closeSettingsModal')
|
||||||
|
this.$store.dispatch('logout')
|
||||||
|
},
|
||||||
peekModal () {
|
peekModal () {
|
||||||
this.$store.dispatch('togglePeekSettingsModal')
|
this.$store.dispatch('togglePeekSettingsModal')
|
||||||
},
|
},
|
||||||
|
@ -150,6 +157,7 @@ const SettingsModal = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
currentUser () { return this.$store.state.users.currentUser },
|
||||||
currentSaveStateNotice () {
|
currentSaveStateNotice () {
|
||||||
return this.$store.state.interface.settings.currentSaveStateNotice
|
return this.$store.state.interface.settings.currentSaveStateNotice
|
||||||
},
|
},
|
||||||
|
|
|
@ -71,5 +71,11 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logout-button {
|
||||||
|
position: absolute;
|
||||||
|
right: 20px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,20 @@
|
||||||
id="unscrolled-content"
|
id="unscrolled-content"
|
||||||
class="extra-content"
|
class="extra-content"
|
||||||
/>
|
/>
|
||||||
|
<button
|
||||||
|
v-if="currentUser"
|
||||||
|
class="button-default logout-button"
|
||||||
|
:title="$t('login.logout')"
|
||||||
|
:aria-label="$t('login.logout')"
|
||||||
|
@click.prevent="logout"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="sign-out-alt"
|
||||||
|
/>
|
||||||
|
<span>{{ $t('login.logout') }}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -37,6 +37,15 @@
|
||||||
{{ $t('settings.hide_muted_posts') }}
|
{{ $t('settings.hide_muted_posts') }}
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
v-if="user"
|
||||||
|
:disabled="hideFilteredStatuses"
|
||||||
|
path="hideThreadsWithBlockedUsers"
|
||||||
|
>
|
||||||
|
{{ $t('settings.hide_threads_with_blocked_users') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
|
|
@ -50,6 +50,7 @@ const GeneralTab = {
|
||||||
Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'webkitAudioDecodedByteCount') ||
|
Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'webkitAudioDecodedByteCount') ||
|
||||||
// Future spec, still not supported in Nightly 63 as of 08/2018
|
// Future spec, still not supported in Nightly 63 as of 08/2018
|
||||||
Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'audioTracks')
|
Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'audioTracks')
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -82,11 +83,20 @@ const GeneralTab = {
|
||||||
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
|
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
translationLanguage: {
|
||||||
|
get: function () { return this.$store.getters.mergedConfig.translationLanguage },
|
||||||
|
set: function (val) {
|
||||||
|
this.$store.dispatch('setOption', { name: 'translationLanguage', value: val })
|
||||||
|
}
|
||||||
|
},
|
||||||
...SharedComputedObject()
|
...SharedComputedObject()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeDefaultScope (value) {
|
changeDefaultScope (value) {
|
||||||
this.$store.dispatch('setServerSideOption', { name: 'defaultScope', value })
|
this.$store.dispatch('setServerSideOption', { name: 'defaultScope', value })
|
||||||
|
},
|
||||||
|
setTranslationLanguage (value) {
|
||||||
|
this.$store.dispatch('setOption', { name: 'translationLanguage', value })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,38 @@
|
||||||
{{ $t('settings.hide_wallpaper') }}
|
{{ $t('settings.hide_wallpaper') }}
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="hideSiteFavicon"
|
||||||
|
expert="1"
|
||||||
|
>
|
||||||
|
{{ $t('settings.hide_site_favicon') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="hideSiteName"
|
||||||
|
expert="1"
|
||||||
|
>
|
||||||
|
{{ $t('settings.hide_site_name') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="showNavShortcuts"
|
||||||
|
expert="1"
|
||||||
|
>
|
||||||
|
{{ $t('settings.show_nav_shortcuts') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="showWiderShortcuts"
|
||||||
|
expert="1"
|
||||||
|
>
|
||||||
|
{{ $t('settings.show_wider_shortcuts') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<BooleanSetting path="stopGifs">
|
<BooleanSetting path="stopGifs">
|
||||||
{{ $t('settings.stop_gifs') }}
|
{{ $t('settings.stop_gifs') }}
|
||||||
|
@ -103,6 +135,28 @@
|
||||||
<BooleanSetting path="renderMisskeyMarkdown">
|
<BooleanSetting path="renderMisskeyMarkdown">
|
||||||
{{ $t('settings.render_mfm') }}
|
{{ $t('settings.render_mfm') }}
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
|
<ul
|
||||||
|
class="setting-list suboptions"
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="mfmOnHover"
|
||||||
|
:disabled="!renderMisskeyMarkdown"
|
||||||
|
>
|
||||||
|
{{ $t('settings.render_mfm_on_hover') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>
|
||||||
|
<interface-language-switcher
|
||||||
|
:globe-icon="false"
|
||||||
|
:prompt-text="$t('settings.translation_language')"
|
||||||
|
:language="translationLanguage"
|
||||||
|
:set-language="setTranslationLanguage"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
|
@ -120,6 +174,77 @@
|
||||||
{{ $t('settings.autohide_floating_post_button') }}
|
{{ $t('settings.autohide_floating_post_button') }}
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<h3>{{ $t('settings.columns') }}</h3>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="disableStickyHeaders">
|
||||||
|
{{ $t('settings.disable_sticky_headers') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="showScrollbars">
|
||||||
|
{{ $t('settings.show_scrollbars') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="sidebarRight">
|
||||||
|
{{ $t('settings.right_sidebar') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<ChoiceSetting
|
||||||
|
v-if="user"
|
||||||
|
id="thirdColumnMode"
|
||||||
|
path="thirdColumnMode"
|
||||||
|
:options="thirdColumnModeOptions"
|
||||||
|
>
|
||||||
|
{{ $t('settings.third_column_mode') }}
|
||||||
|
</ChoiceSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<h3>{{ $t('settings.confirmation_dialogs') }}</h3>
|
||||||
|
</li>
|
||||||
|
<li class="select-multiple">
|
||||||
|
<span class="label">{{ $t('settings.confirm_dialogs') }}</span>
|
||||||
|
<ul class="option-list">
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="modalOnRepeat">
|
||||||
|
{{ $t('settings.confirm_dialogs_repeat') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="modalOnUnfollow">
|
||||||
|
{{ $t('settings.confirm_dialogs_unfollow') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="modalOnBlock">
|
||||||
|
{{ $t('settings.confirm_dialogs_block') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="modalOnMute">
|
||||||
|
{{ $t('settings.confirm_dialogs_mute') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="modalOnDelete">
|
||||||
|
{{ $t('settings.confirm_dialogs_delete') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="modalOnApproveFollow">
|
||||||
|
{{ $t('settings.confirm_dialogs_approve_follow') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="modalOnDenyFollow">
|
||||||
|
{{ $t('settings.confirm_dialogs_deny_follow') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { extractCommit } from 'src/services/version/version.service'
|
import { extractCommit } from 'src/services/version/version.service'
|
||||||
|
|
||||||
const pleromaFeCommitUrl = 'https://akkoma.dev/AkkomaGang/pleroma-fe/commit/'
|
const pleromaFeCommitUrl = 'https://akkoma.dev/eris/pleroma-fe/commit/'
|
||||||
const pleromaBeCommitUrl = 'https://akkoma.dev/AkkomaGang/akkoma/commit/'
|
const pleromaBeCommitUrl = 'https://akkoma.dev/AkkomaGang/akkoma/commit/'
|
||||||
|
|
||||||
const VersionTab = {
|
const VersionTab = {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
faSignOutAlt,
|
faSignOutAlt,
|
||||||
faHome,
|
faHome,
|
||||||
faComments,
|
faComments,
|
||||||
faBell,
|
faBolt,
|
||||||
faUserPlus,
|
faUserPlus,
|
||||||
faBullhorn,
|
faBullhorn,
|
||||||
faSearch,
|
faSearch,
|
||||||
|
@ -23,7 +23,7 @@ library.add(
|
||||||
faSignOutAlt,
|
faSignOutAlt,
|
||||||
faHome,
|
faHome,
|
||||||
faComments,
|
faComments,
|
||||||
faBell,
|
faBolt,
|
||||||
faUserPlus,
|
faUserPlus,
|
||||||
faBullhorn,
|
faBullhorn,
|
||||||
faSearch,
|
faSearch,
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
class="fa-scale-110 fa-old-padding"
|
class="fa-scale-110 fa-old-padding"
|
||||||
icon="bell"
|
icon="bolt"
|
||||||
/> {{ $t("nav.interactions") }}
|
/> {{ $t("nav.interactions") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
:key="group.role"
|
:key="group.role"
|
||||||
class="staff-group"
|
class="staff-group"
|
||||||
>
|
>
|
||||||
<h4>{{ $t('general.role.' + group.role) }}</h4>
|
<h4>The Admin Team</h4>
|
||||||
<basic-user-card
|
<basic-user-card
|
||||||
v-for="user in group.users"
|
v-for="user in group.users"
|
||||||
:key="user.screen_name"
|
:key="user.screen_name"
|
||||||
|
@ -30,10 +30,21 @@
|
||||||
|
|
||||||
.staff-group {
|
.staff-group {
|
||||||
padding-left: 1em;
|
padding-left: 1em;
|
||||||
padding-top: 1em;
|
padding-top: 0.2em;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
|
||||||
.basic-user-card {
|
.basic-user-card {
|
||||||
|
padding: 0.6em 0.4em;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.basic-user-card-collapsed-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.still-image {
|
||||||
|
border-radius: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ import {
|
||||||
faStar,
|
faStar,
|
||||||
faEyeSlash,
|
faEyeSlash,
|
||||||
faEye,
|
faEye,
|
||||||
|
faBiohazard,
|
||||||
faThumbtack,
|
faThumbtack,
|
||||||
faChevronUp,
|
faChevronUp,
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
|
@ -56,6 +57,7 @@ library.add(
|
||||||
faEllipsisH,
|
faEllipsisH,
|
||||||
faEyeSlash,
|
faEyeSlash,
|
||||||
faEye,
|
faEye,
|
||||||
|
faBiohazard,
|
||||||
faThumbtack,
|
faThumbtack,
|
||||||
faChevronUp,
|
faChevronUp,
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
|
@ -261,6 +263,38 @@ const Status = {
|
||||||
hasMentionsLine () {
|
hasMentionsLine () {
|
||||||
return this.mentionsLine.length > 0
|
return this.mentionsLine.length > 0
|
||||||
},
|
},
|
||||||
|
mentionsBlockedUser () {
|
||||||
|
// XXX: doesn't work on domain blocks, because users from blocked domains
|
||||||
|
// don't appear in `attentions' and therefore cannot be filtered.
|
||||||
|
let mentions = false
|
||||||
|
|
||||||
|
// find if user in mentions list is blocked
|
||||||
|
this.status.attentions.forEach((attn) => {
|
||||||
|
if (attn.id === this.currentUser.id) return
|
||||||
|
const relationship = this.$store.getters.relationship(attn.id)
|
||||||
|
if (relationship.blocking) {
|
||||||
|
mentions = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return mentions
|
||||||
|
},
|
||||||
|
mentionsMutedUser () {
|
||||||
|
// XXX: doesn't work on domain blocks, because users from blocked domains
|
||||||
|
// don't appear in `attentions' and therefore cannot be filtered.
|
||||||
|
let mentions = false
|
||||||
|
|
||||||
|
// find if user in mentions list is blocked
|
||||||
|
this.status.attentions.forEach((attn) => {
|
||||||
|
if (attn.id === this.currentUser.id) return
|
||||||
|
const relationship = this.$store.getters.relationship(attn.id)
|
||||||
|
if (relationship.muting) {
|
||||||
|
mentions = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return mentions
|
||||||
|
},
|
||||||
muted () {
|
muted () {
|
||||||
if (this.statusoid.user.id === this.currentUser.id) return false
|
if (this.statusoid.user.id === this.currentUser.id) return false
|
||||||
const reasonsToMute = this.userIsMuted ||
|
const reasonsToMute = this.userIsMuted ||
|
||||||
|
@ -269,7 +303,11 @@ const Status = {
|
||||||
// Wordfiltered
|
// Wordfiltered
|
||||||
this.muteWordHits.length > 0 ||
|
this.muteWordHits.length > 0 ||
|
||||||
// bot status
|
// bot status
|
||||||
(this.muteBotStatuses && this.botStatus && !this.compact)
|
(this.muteBotStatuses && this.botStatus && !this.compact) ||
|
||||||
|
// mentions blocked user
|
||||||
|
this.mentionsBlockedUser ||
|
||||||
|
// mentions muted user
|
||||||
|
this.mentionsMutedUser
|
||||||
return !this.unmuted && !this.shouldNotMute && reasonsToMute
|
return !this.unmuted && !this.shouldNotMute && reasonsToMute
|
||||||
},
|
},
|
||||||
userIsMuted () {
|
userIsMuted () {
|
||||||
|
@ -312,6 +350,9 @@ const Status = {
|
||||||
hideFilteredStatuses () {
|
hideFilteredStatuses () {
|
||||||
return this.mergedConfig.hideFilteredStatuses
|
return this.mergedConfig.hideFilteredStatuses
|
||||||
},
|
},
|
||||||
|
hideThreadsWithBlockedUsers () {
|
||||||
|
return this.mergedConfig.hideThreadsWithBlockedUsers
|
||||||
|
},
|
||||||
hideWordFilteredPosts () {
|
hideWordFilteredPosts () {
|
||||||
return this.mergedConfig.hideWordFilteredPosts
|
return this.mergedConfig.hideWordFilteredPosts
|
||||||
},
|
},
|
||||||
|
@ -319,8 +360,9 @@ const Status = {
|
||||||
return (!this.shouldNotMute) && (
|
return (!this.shouldNotMute) && (
|
||||||
(this.muted && this.hideFilteredStatuses) ||
|
(this.muted && this.hideFilteredStatuses) ||
|
||||||
(this.userIsMuted && this.hideMutedUsers) ||
|
(this.userIsMuted && this.hideMutedUsers) ||
|
||||||
(this.status.thread_muted && this.hideMutedThreads) ||
|
((this.status.thread_muted || this.mentionsMutedUser) && this.hideMutedThreads) ||
|
||||||
(this.muteWordHits.length > 0 && this.hideWordFilteredPosts)
|
(this.muteWordHits.length > 0 && this.hideWordFilteredPosts) ||
|
||||||
|
(this.mentionsBlockedUser && this.hideThreadsWithBlockedUsers)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
isFocused () {
|
isFocused () {
|
||||||
|
@ -397,6 +439,12 @@ const Status = {
|
||||||
},
|
},
|
||||||
visibilityLocalized () {
|
visibilityLocalized () {
|
||||||
return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility)
|
return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility)
|
||||||
|
},
|
||||||
|
isEdited () {
|
||||||
|
return this.status.edited_at !== null
|
||||||
|
},
|
||||||
|
editingAvailable () {
|
||||||
|
return this.$store.state.instance.editingAvailable
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -409,7 +457,7 @@ const Status = {
|
||||||
case 'direct':
|
case 'direct':
|
||||||
return 'envelope'
|
return 'envelope'
|
||||||
case 'local':
|
case 'local':
|
||||||
return 'users'
|
return 'biohazard'
|
||||||
default:
|
default:
|
||||||
return 'globe'
|
return 'globe'
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,9 +162,9 @@
|
||||||
|
|
||||||
& .heading-reply-row {
|
& .heading-reply-row {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin-top: 0.2em;
|
||||||
align-content: baseline;
|
align-content: baseline;
|
||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
margin-top: 0.2em;
|
|
||||||
line-height: 130%;
|
line-height: 130%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
|
|
|
@ -187,8 +187,29 @@
|
||||||
>
|
>
|
||||||
<Timeago
|
<Timeago
|
||||||
:time="status.created_at"
|
:time="status.created_at"
|
||||||
|
:with-direction="true"
|
||||||
:auto-update="60"
|
:auto-update="60"
|
||||||
/>
|
/>
|
||||||
|
<i18n-t
|
||||||
|
v-if="isEdited && editingAvailable && !isPreview"
|
||||||
|
keypath="status.edited_at"
|
||||||
|
tag="span"
|
||||||
|
class="edited-row"
|
||||||
|
>
|
||||||
|
<template #time>
|
||||||
|
<i18n-t
|
||||||
|
keypath="time.in_past"
|
||||||
|
tag="span"
|
||||||
|
>
|
||||||
|
<template>
|
||||||
|
<Timeago
|
||||||
|
:time="status.edited_at"
|
||||||
|
:auto-update="60"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
</router-link>
|
</router-link>
|
||||||
<span
|
<span
|
||||||
v-if="status.visibility"
|
v-if="status.visibility"
|
||||||
|
@ -453,6 +474,7 @@
|
||||||
:status="status"
|
:status="status"
|
||||||
@onError="showError"
|
@onError="showError"
|
||||||
@onSuccess="clearError"
|
@onSuccess="clearError"
|
||||||
|
@quote-toggle="toggleQuoting"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,10 +4,20 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
.translation {
|
||||||
|
border: 1px solid var(--accent, $fallback--link);
|
||||||
|
border-radius: var(--panelRadius, $fallback--panelRadius);
|
||||||
|
margin-top: 1em;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
.emoji {
|
.emoji {
|
||||||
--_still_image-label-scale: 0.5;
|
--_still_image-label-scale: 0.5;
|
||||||
--emoji-size: 50px;
|
--emoji-size: 38px;
|
||||||
--emoji-size: 50px;
|
}
|
||||||
|
|
||||||
|
.emoji:hover {
|
||||||
|
transform: scale(1.4);
|
||||||
|
transition: 0.05s;
|
||||||
}
|
}
|
||||||
|
|
||||||
._mfm_x2_ {
|
._mfm_x2_ {
|
||||||
|
@ -93,7 +103,7 @@
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
.media-body {
|
.media-body-wrapper {
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
mask:
|
mask:
|
||||||
linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat,
|
linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat,
|
||||||
|
@ -143,26 +153,25 @@
|
||||||
color: var(--postGreentext, $fallback--cGreen);
|
color: var(--postGreentext, $fallback--cGreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cyantext {
|
|
||||||
color: var(--postCyantext, $fallback--cBlue);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.-compact {
|
&.-compact {
|
||||||
align-items: top;
|
align-items: top;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
--emoji-size: 16px;
|
--emoji-size: 16px;
|
||||||
|
|
||||||
& .body,
|
& .body:not(:active),
|
||||||
& .attachments {
|
& .attachments {
|
||||||
max-height: 3.25em;
|
max-height: 3.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.body {
|
.body {
|
||||||
overflow: hidden;
|
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
min-width: 5em;
|
min-width: 5em;
|
||||||
flex: 5 1 auto;
|
flex: 5 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body:not(:active) {
|
||||||
|
overflow: hidden;
|
||||||
mask-size: auto 3.5em, auto auto;
|
mask-size: auto 3.5em, auto auto;
|
||||||
mask-position: 0 0, 0 0;
|
mask-position: 0 0, 0 0;
|
||||||
mask-repeat: repeat-x, repeat;
|
mask-repeat: repeat-x, repeat;
|
||||||
|
@ -197,3 +206,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
v-if="!hideSubjectStatus && !(singleLine && status.summary_raw_html)"
|
v-if="!hideSubjectStatus && !(singleLine && status.summary_raw_html)"
|
||||||
|
class="media-body-wrapper"
|
||||||
>
|
>
|
||||||
<RichContent
|
<RichContent
|
||||||
:class="{ '-single-line': singleLine }"
|
:class="{ '-single-line': singleLine }"
|
||||||
|
@ -55,6 +56,23 @@
|
||||||
:attentions="status.attentions"
|
:attentions="status.attentions"
|
||||||
@parseReady="onParseReady"
|
@parseReady="onParseReady"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
v-if="status.translation"
|
||||||
|
class="translation"
|
||||||
|
>
|
||||||
|
<h4>{{ $t('status.translated_from', { language: status.translation.detected_language }) }}</h4>
|
||||||
|
<RichContent
|
||||||
|
:class="{ '-single-line': singleLine }"
|
||||||
|
class="text media-body"
|
||||||
|
:html="status.translation.text"
|
||||||
|
:emoji="status.emojis"
|
||||||
|
:handle-links="true"
|
||||||
|
:mfm="renderMisskeyMarkdown && (status.media_type === 'text/x.misskeymarkdown')"
|
||||||
|
:greentext="mergedConfig.greentext"
|
||||||
|
:attentions="status.attentions"
|
||||||
|
@parseReady="onParseReady"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
v-show="hideSubjectStatus"
|
v-show="hideSubjectStatus"
|
||||||
|
|
|
@ -100,6 +100,9 @@ const StatusContent = {
|
||||||
maxThumbnails () {
|
maxThumbnails () {
|
||||||
return this.mergedConfig.maxThumbnails
|
return this.mergedConfig.maxThumbnails
|
||||||
},
|
},
|
||||||
|
mfmOnHover () {
|
||||||
|
return this.mergedConfig.mfmOnHover
|
||||||
|
},
|
||||||
...mapGetters(['mergedConfig']),
|
...mapGetters(['mergedConfig']),
|
||||||
...mapState({
|
...mapState({
|
||||||
currentUser: state => state.users.currentUser
|
currentUser: state => state.users.currentUser
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="StatusContent"
|
class="StatusContent"
|
||||||
:class="{ '-compact': compact }"
|
:class="{ '-compact': compact, 'mfm-hover': mfmOnHover }"
|
||||||
>
|
>
|
||||||
<slot name="header" />
|
<slot name="header" />
|
||||||
<StatusBody
|
<StatusBody
|
||||||
|
@ -75,5 +75,17 @@
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.mfm-hover:not(:hover) {
|
||||||
|
.mfm {
|
||||||
|
animation: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote-inline,
|
||||||
|
.quote + .link-preview {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
60
src/components/status_history_modal/status_history_modal.js
Normal file
60
src/components/status_history_modal/status_history_modal.js
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import { get } from 'lodash'
|
||||||
|
import Modal from '../modal/modal.vue'
|
||||||
|
import Status from '../status/status.vue'
|
||||||
|
|
||||||
|
const StatusHistoryModal = {
|
||||||
|
components: {
|
||||||
|
Modal,
|
||||||
|
Status
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
statuses: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
modalActivated () {
|
||||||
|
return this.$store.state.statusHistory.modalActivated
|
||||||
|
},
|
||||||
|
params () {
|
||||||
|
return this.$store.state.statusHistory.params
|
||||||
|
},
|
||||||
|
statusId () {
|
||||||
|
return this.params.id
|
||||||
|
},
|
||||||
|
historyCount () {
|
||||||
|
return this.statuses.length
|
||||||
|
},
|
||||||
|
history () {
|
||||||
|
return this.statuses
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
params (newVal, oldVal) {
|
||||||
|
const newStatusId = get(newVal, 'id') !== get(oldVal, 'id')
|
||||||
|
if (newStatusId) {
|
||||||
|
this.resetHistory()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newStatusId || get(newVal, 'edited_at') !== get(oldVal, 'edited_at')) {
|
||||||
|
this.fetchStatusHistory()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
resetHistory () {
|
||||||
|
this.statuses = []
|
||||||
|
},
|
||||||
|
fetchStatusHistory () {
|
||||||
|
this.$store.dispatch('fetchStatusHistory', this.params)
|
||||||
|
.then(data => {
|
||||||
|
this.statuses = data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
closeModal () {
|
||||||
|
this.$store.dispatch('closeStatusHistoryModal')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StatusHistoryModal
|
46
src/components/status_history_modal/status_history_modal.vue
Normal file
46
src/components/status_history_modal/status_history_modal.vue
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<template>
|
||||||
|
<Modal
|
||||||
|
v-if="modalActivated"
|
||||||
|
class="status-history-modal-view"
|
||||||
|
@backdropClicked="closeModal"
|
||||||
|
>
|
||||||
|
<div class="status-history-modal-panel panel">
|
||||||
|
<div class="panel-heading">
|
||||||
|
{{ $tc('status.edit_history_modal_title', historyCount - 1, { historyCount: historyCount - 1 }) }}
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div
|
||||||
|
v-if="historyCount > 0"
|
||||||
|
class="history-body"
|
||||||
|
>
|
||||||
|
<status
|
||||||
|
v-for="status in history"
|
||||||
|
:key="status.id"
|
||||||
|
:statusoid="status"
|
||||||
|
:isPreview="true"
|
||||||
|
class="conversation-status status-fadein panel-body"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./status_history_modal.js"></script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.modal-view.status-history-modal-view {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.status-history-modal-panel {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 25%;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 700px;
|
||||||
|
|
||||||
|
@media (orientation: landscape) {
|
||||||
|
margin-top: 8%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -51,6 +51,10 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.animated {
|
&.animated {
|
||||||
|
|
|
@ -3,12 +3,19 @@
|
||||||
:datetime="time"
|
:datetime="time"
|
||||||
:title="localeDateString"
|
:title="localeDateString"
|
||||||
:class="{ warning: relativeTime.direction === 'time.in_future' }"
|
:class="{ warning: relativeTime.direction === 'time.in_future' }"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-if="withDirection"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
relativeTime.direction === '' ?
|
relativeTime.direction === '' ?
|
||||||
$tc(relativeTime.key, relativeTime.num, [relativeTime.num]) :
|
$tc(relativeTime.key, relativeTime.num, [relativeTime.num]) :
|
||||||
$t(relativeTime.direction, [$tc(relativeTime.key, relativeTime.num, [relativeTime.num])])
|
$t(relativeTime.direction, [$tc(relativeTime.key, relativeTime.num, [relativeTime.num])])
|
||||||
}}
|
}}
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{ $tc(relativeTime.key, relativeTime.num, [relativeTime.num]) }}
|
||||||
|
</template>
|
||||||
</time>
|
</time>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -18,7 +25,7 @@ import localeService from 'src/services/locale/locale.service.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Timeago',
|
name: 'Timeago',
|
||||||
props: ['time', 'autoUpdate', 'longFormat', 'nowThreshold'],
|
props: ['time', 'autoUpdate', 'longFormat', 'nowThreshold', 'withDirection'],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
relativeTime: { key: 'time.now', num: 0 },
|
relativeTime: { key: 'time.now', num: 0 },
|
||||||
|
@ -58,7 +65,9 @@ export default {
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../../_variables.scss';
|
@import '../../_variables.scss';
|
||||||
|
.timeago {
|
||||||
time.warning {
|
time.warning {
|
||||||
color: var(--alertWarning, $fallback--alertWarning);
|
color: var(--alertWarning, $fallback--alertWarning);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -145,7 +145,9 @@ const Timeline = {
|
||||||
this.$store.commit('showNewStatuses', { timeline: this.timelineName })
|
this.$store.commit('showNewStatuses', { timeline: this.timelineName })
|
||||||
this.paused = false
|
this.paused = false
|
||||||
}
|
}
|
||||||
|
if (!this.inProfile) {
|
||||||
window.scrollTo({ top: 0 })
|
window.scrollTo({ top: 0 })
|
||||||
|
}
|
||||||
},
|
},
|
||||||
fetchOlderStatuses: throttle(function () {
|
fetchOlderStatuses: throttle(function () {
|
||||||
const store = this.$store
|
const store = this.$store
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
faBookmark,
|
faBookmark,
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faHome,
|
faHome,
|
||||||
faCircle
|
faCommentMedical
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
|
@ -15,7 +15,7 @@ library.add(
|
||||||
faBookmark,
|
faBookmark,
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faHome,
|
faHome,
|
||||||
faCircle
|
faCommentMedical
|
||||||
)
|
)
|
||||||
|
|
||||||
const TimelineMenuContent = {
|
const TimelineMenuContent = {
|
||||||
|
|
|
@ -9,22 +9,8 @@
|
||||||
fixed-width
|
fixed-width
|
||||||
class="fa-scale-110 fa-old-padding "
|
class="fa-scale-110 fa-old-padding "
|
||||||
icon="home"
|
icon="home"
|
||||||
/>{{ $t("nav.home_timeline") }}
|
/><span :title="$t('nav.home_timeline_description')">{{ $t("nav.home_timeline") }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
<span class="timeline-desc">{{ $t("nav.home_timeline_description") }}</span>
|
|
||||||
</li>
|
|
||||||
<li v-if="currentUser">
|
|
||||||
<router-link
|
|
||||||
class="menu-item"
|
|
||||||
:to="{ name: 'bubble-timeline' }"
|
|
||||||
>
|
|
||||||
<FAIcon
|
|
||||||
fixed-width
|
|
||||||
class="fa-scale-110 fa-old-padding "
|
|
||||||
icon="circle"
|
|
||||||
/>{{ $t("nav.bubble_timeline") }}
|
|
||||||
</router-link>
|
|
||||||
<span class="timeline-desc">{{ $t("nav.bubble_timeline_description") }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="currentUser || !privateMode">
|
<li v-if="currentUser || !privateMode">
|
||||||
<router-link
|
<router-link
|
||||||
|
@ -35,9 +21,8 @@
|
||||||
fixed-width
|
fixed-width
|
||||||
class="fa-scale-110 fa-old-padding "
|
class="fa-scale-110 fa-old-padding "
|
||||||
icon="users"
|
icon="users"
|
||||||
/>{{ $t("nav.public_tl") }}
|
/><span :title="$t('nav.public_timeline_description')">{{ $t("nav.public_tl") }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
<span class="timeline-desc">{{ $t("nav.public_timeline_description") }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="federating && (currentUser || !privateMode)">
|
<li v-if="federating && (currentUser || !privateMode)">
|
||||||
<router-link
|
<router-link
|
||||||
|
@ -48,9 +33,20 @@
|
||||||
fixed-width
|
fixed-width
|
||||||
class="fa-scale-110 fa-old-padding "
|
class="fa-scale-110 fa-old-padding "
|
||||||
icon="globe"
|
icon="globe"
|
||||||
/>{{ $t("nav.twkn") }}
|
/><span :title="$t('nav.twkn_timeline_description')">{{ $t("nav.twkn") }}</span>
|
||||||
|
</router-link>
|
||||||
|
</li>
|
||||||
|
<li v-if="currentUser">
|
||||||
|
<router-link
|
||||||
|
class="menu-item"
|
||||||
|
:to="{ name: 'bubble-timeline' }"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding "
|
||||||
|
icon="comment-medical"
|
||||||
|
/><span :title="$t('nav.bubble_timeline_description')">{{ $t("nav.bubble_timeline") }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
<span class="timeline-desc">{{ $t("nav.twkn_timeline_description") }}</span>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="currentUser">
|
<li v-if="currentUser">
|
||||||
<router-link
|
<router-link
|
||||||
|
|
|
@ -6,6 +6,7 @@ import ModerationTools from '../moderation_tools/moderation_tools.vue'
|
||||||
import AccountActions from '../account_actions/account_actions.vue'
|
import AccountActions from '../account_actions/account_actions.vue'
|
||||||
import Select from '../select/select.vue'
|
import Select from '../select/select.vue'
|
||||||
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||||
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
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'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
@ -32,7 +33,8 @@ export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
followRequestInProgress: false,
|
followRequestInProgress: false,
|
||||||
betterShadow: this.$store.state.interface.browserSupport.cssFilter
|
betterShadow: this.$store.state.interface.browserSupport.cssFilter,
|
||||||
|
showingConfirmMute: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
@ -112,6 +114,9 @@ export default {
|
||||||
hideFollowersCount () {
|
hideFollowersCount () {
|
||||||
return this.isOtherUser && this.user.hide_followers_count
|
return this.isOtherUser && this.user.hide_followers_count
|
||||||
},
|
},
|
||||||
|
shouldConfirmMute () {
|
||||||
|
return this.mergedConfig.modalOnMute
|
||||||
|
},
|
||||||
...mapGetters(['mergedConfig'])
|
...mapGetters(['mergedConfig'])
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -122,14 +127,29 @@ export default {
|
||||||
ProgressButton,
|
ProgressButton,
|
||||||
FollowButton,
|
FollowButton,
|
||||||
Select,
|
Select,
|
||||||
RichContent
|
RichContent,
|
||||||
|
ConfirmModal
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
refetchRelationship () {
|
refetchRelationship () {
|
||||||
return this.$store.dispatch('fetchUserRelationship', this.user.id)
|
return this.$store.dispatch('fetchUserRelationship', this.user.id)
|
||||||
},
|
},
|
||||||
|
showConfirmMute () {
|
||||||
|
this.showingConfirmMute = true
|
||||||
|
},
|
||||||
|
hideConfirmMute () {
|
||||||
|
this.showingConfirmMute = false
|
||||||
|
},
|
||||||
muteUser () {
|
muteUser () {
|
||||||
|
if (!this.shouldConfirmMute) {
|
||||||
|
this.doMuteUser()
|
||||||
|
} else {
|
||||||
|
this.showConfirmMute()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doMuteUser () {
|
||||||
this.$store.dispatch('muteUser', this.user.id)
|
this.$store.dispatch('muteUser', this.user.id)
|
||||||
|
this.hideConfirmMute()
|
||||||
},
|
},
|
||||||
unmuteUser () {
|
unmuteUser () {
|
||||||
this.$store.dispatch('unmuteUser', this.user.id)
|
this.$store.dispatch('unmuteUser', this.user.id)
|
||||||
|
|
|
@ -295,6 +295,27 @@
|
||||||
:handle-links="true"
|
:handle-links="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<teleport to="#modal">
|
||||||
|
<confirm-modal
|
||||||
|
v-if="showingConfirmMute"
|
||||||
|
:title="$t('user_card.mute_confirm_title')"
|
||||||
|
:confirm-text="$t('user_card.mute_confirm_accept_button')"
|
||||||
|
:cancel-text="$t('user_card.mute_confirm_cancel_button')"
|
||||||
|
@accepted="doMuteUser"
|
||||||
|
@cancelled="hideConfirmMute"
|
||||||
|
>
|
||||||
|
<i18n-t
|
||||||
|
keypath="user_card.mute_confirm"
|
||||||
|
tag="span"
|
||||||
|
>
|
||||||
|
<template #user>
|
||||||
|
<span
|
||||||
|
v-text="user.screen_name_ui"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
</confirm-modal>
|
||||||
|
</teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,9 @@ const UserProfile = {
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
const routeParams = this.$route.params
|
const routeParams = this.$route.params
|
||||||
|
const hash = get(this.$route, 'hash', defaultTabKey).replace(/^#/, '')
|
||||||
|
if (hash !== '') this.tab = hash
|
||||||
this.load(routeParams.name || routeParams.id)
|
this.load(routeParams.name || routeParams.id)
|
||||||
this.tab = get(this.$route, 'query.tab', defaultTabKey)
|
|
||||||
},
|
},
|
||||||
unmounted () {
|
unmounted () {
|
||||||
this.stopFetching()
|
this.stopFetching()
|
||||||
|
@ -58,6 +59,9 @@ const UserProfile = {
|
||||||
timeline () {
|
timeline () {
|
||||||
return this.$store.state.statuses.timelines.user
|
return this.$store.state.statuses.timelines.user
|
||||||
},
|
},
|
||||||
|
replies () {
|
||||||
|
return this.$store.state.statuses.timelines.replies
|
||||||
|
},
|
||||||
favorites () {
|
favorites () {
|
||||||
return this.$store.state.statuses.timelines.favorites
|
return this.$store.state.statuses.timelines.favorites
|
||||||
},
|
},
|
||||||
|
@ -82,28 +86,37 @@ const UserProfile = {
|
||||||
},
|
},
|
||||||
currentUser () {
|
currentUser () {
|
||||||
return this.$store.state.users.currentUser
|
return this.$store.state.users.currentUser
|
||||||
}
|
},
|
||||||
|
privateMode () { return this.$store.state.instance.private }
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setFooterRef (el) {
|
setFooterRef (el) {
|
||||||
this.footerRef = el
|
this.footerRef = el
|
||||||
},
|
},
|
||||||
load (userNameOrId) {
|
onRouteChange (previousTab, nextTab) {
|
||||||
const startFetchingTimeline = (timeline, userId) => {
|
const timelineTabMap = {
|
||||||
// Clear timeline only if load another user's profile
|
statuses: 'user',
|
||||||
if (userId !== this.$store.state.statuses.timelines[timeline].userId) {
|
replies: 'replies',
|
||||||
this.$store.commit('clearTimeline', { timeline })
|
media: 'media'
|
||||||
}
|
|
||||||
this.$store.dispatch('startFetchingTimeline', { timeline, userId })
|
|
||||||
}
|
}
|
||||||
|
// only we can see our own favourites
|
||||||
|
if (this.isUs) timelineTabMap['favorites'] = 'favorites'
|
||||||
|
|
||||||
|
const timeline = timelineTabMap[nextTab]
|
||||||
|
|
||||||
|
if (timeline) {
|
||||||
|
this.stopFetching()
|
||||||
|
this.$store.dispatch('startFetchingTimeline', { timeline: timeline, userId: this.userId })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
load (userNameOrId) {
|
||||||
const loadById = (userId) => {
|
const loadById = (userId) => {
|
||||||
this.userId = userId
|
this.userId = userId
|
||||||
startFetchingTimeline('user', userId)
|
const timelines = ['user', 'favorites', 'replies', 'media']
|
||||||
startFetchingTimeline('media', userId)
|
timelines.forEach((timeline) => {
|
||||||
if (this.isUs) {
|
this.$store.commit('clearTimeline', { timeline: timeline })
|
||||||
startFetchingTimeline('favorites', userId)
|
})
|
||||||
}
|
this.onRouteChange(null, this.tab)
|
||||||
// Fetch all pinned statuses immediately
|
// Fetch all pinned statuses immediately
|
||||||
this.$store.dispatch('fetchPinnedStatuses', userId)
|
this.$store.dispatch('fetchPinnedStatuses', userId)
|
||||||
}
|
}
|
||||||
|
@ -137,6 +150,7 @@ const UserProfile = {
|
||||||
},
|
},
|
||||||
stopFetching () {
|
stopFetching () {
|
||||||
this.$store.dispatch('stopFetchingTimeline', 'user')
|
this.$store.dispatch('stopFetchingTimeline', 'user')
|
||||||
|
this.$store.dispatch('stopFetchingTimeline', 'replies')
|
||||||
this.$store.dispatch('stopFetchingTimeline', 'favorites')
|
this.$store.dispatch('stopFetchingTimeline', 'favorites')
|
||||||
this.$store.dispatch('stopFetchingTimeline', 'media')
|
this.$store.dispatch('stopFetchingTimeline', 'media')
|
||||||
},
|
},
|
||||||
|
@ -146,7 +160,7 @@ const UserProfile = {
|
||||||
},
|
},
|
||||||
onTabSwitch (tab) {
|
onTabSwitch (tab) {
|
||||||
this.tab = tab
|
this.tab = tab
|
||||||
this.$router.replace({ query: { tab } })
|
this.$router.replace({ hash: `#${tab}` })
|
||||||
},
|
},
|
||||||
linkClicked ({ target }) {
|
linkClicked ({ target }) {
|
||||||
if (target.tagName === 'SPAN') {
|
if (target.tagName === 'SPAN') {
|
||||||
|
@ -176,8 +190,10 @@ const UserProfile = {
|
||||||
this.switchUser(newVal)
|
this.switchUser(newVal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'$route.query': function (newVal) {
|
'$route.hash': function (newVal) {
|
||||||
this.tab = newVal.tab || defaultTabKey
|
const oldTab = this.tab
|
||||||
|
this.tab = newVal.replace(/^#/, '') || defaultTabKey
|
||||||
|
this.onRouteChange(oldTab, this.tab)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -79,6 +79,26 @@
|
||||||
:in-profile="true"
|
:in-profile="true"
|
||||||
:footer-slipgate="footerRef"
|
:footer-slipgate="footerRef"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
v-if="!currentUser"
|
||||||
|
key="replies-disabled"
|
||||||
|
:label="$t('user_card.replies')"
|
||||||
|
:title="$t('user_card.replies')"
|
||||||
|
:disabled="!currentUser"
|
||||||
|
/>
|
||||||
|
<Timeline
|
||||||
|
v-else-if="currentUser"
|
||||||
|
key="replies"
|
||||||
|
:label="$t('user_card.replies')"
|
||||||
|
:count="user.statuses_count"
|
||||||
|
:embedded="true"
|
||||||
|
:title="$t('user_card.replies')"
|
||||||
|
:timeline="replies"
|
||||||
|
timeline-name="replies"
|
||||||
|
:user-id="userId"
|
||||||
|
:in-profile="true"
|
||||||
|
:footer-slipgate="footerRef"
|
||||||
|
/>
|
||||||
<div
|
<div
|
||||||
v-if="followsTabVisible"
|
v-if="followsTabVisible"
|
||||||
key="followees"
|
key="followees"
|
||||||
|
@ -107,9 +127,9 @@
|
||||||
</FollowerList>
|
</FollowerList>
|
||||||
</div>
|
</div>
|
||||||
<Timeline
|
<Timeline
|
||||||
|
v-if="currentUser"
|
||||||
key="media"
|
key="media"
|
||||||
:label="$t('user_card.media')"
|
:label="$t('user_card.media')"
|
||||||
:disabled="!media.visibleStatuses.length"
|
|
||||||
:embedded="true"
|
:embedded="true"
|
||||||
:title="$t('user_card.media')"
|
:title="$t('user_card.media')"
|
||||||
timeline-name="media"
|
timeline-name="media"
|
||||||
|
@ -122,7 +142,7 @@
|
||||||
v-if="isUs"
|
v-if="isUs"
|
||||||
key="favorites"
|
key="favorites"
|
||||||
:label="$t('user_card.favorites')"
|
:label="$t('user_card.favorites')"
|
||||||
:disabled="!favorites.visibleStatuses.length"
|
:disabled="!isUs"
|
||||||
:embedded="true"
|
:embedded="true"
|
||||||
:title="$t('user_card.favorites')"
|
:title="$t('user_card.favorites')"
|
||||||
timeline-name="favorites"
|
timeline-name="favorites"
|
||||||
|
@ -136,6 +156,22 @@
|
||||||
class="panel-footer"
|
class="panel-footer"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-else-if="!currentUser && privateMode"
|
||||||
|
class="panel user-profile-placeholder"
|
||||||
|
>
|
||||||
|
<div class="panel-heading">
|
||||||
|
<div class="title">
|
||||||
|
???
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body error">
|
||||||
|
<img
|
||||||
|
class="error-img"
|
||||||
|
src="/static/error.gif"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="panel user-profile-placeholder"
|
class="panel user-profile-placeholder"
|
||||||
|
@ -246,6 +282,15 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: middle;
|
align-items: middle;
|
||||||
padding: 7em;
|
padding: 7em;
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
padding: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-img {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 0px 0px 10px 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
370
src/i18n/ca.json
370
src/i18n/ca.json
|
@ -164,8 +164,8 @@
|
||||||
"fullname_required": "no es pot deixar en blanc",
|
"fullname_required": "no es pot deixar en blanc",
|
||||||
"username_required": "no es pot deixar en blanc"
|
"username_required": "no es pot deixar en blanc"
|
||||||
},
|
},
|
||||||
"fullname_placeholder": "p. ex. Anna Bofarull",
|
"fullname_placeholder": "p. ex. Lain Iwakura",
|
||||||
"username_placeholder": "p. ex. anna",
|
"username_placeholder": "p. ex. lain",
|
||||||
"captcha": "CAPTCHA",
|
"captcha": "CAPTCHA",
|
||||||
"register": "Registre",
|
"register": "Registre",
|
||||||
"reason": "Raó per a registrar-se",
|
"reason": "Raó per a registrar-se",
|
||||||
|
@ -181,99 +181,99 @@
|
||||||
"avatarAltRadius": "Avatars (notificacions)",
|
"avatarAltRadius": "Avatars (notificacions)",
|
||||||
"avatarRadius": "Avatars",
|
"avatarRadius": "Avatars",
|
||||||
"background": "Fons de pantalla",
|
"background": "Fons de pantalla",
|
||||||
"bio": "Presentació",
|
"bio": "Bio",
|
||||||
"btnRadius": "Botons",
|
"btnRadius": "Botons",
|
||||||
"cBlue": "Blau (respon, segueix)",
|
"cBlue": "Blau (respon, segueix)",
|
||||||
"cGreen": "Verd (republica)",
|
"cGreen": "Verd (republica)",
|
||||||
"cOrange": "Taronja (marca com a preferit)",
|
"cOrange": "Taronja (afavoreix)",
|
||||||
"cRed": "Vermell (canceŀla)",
|
"cRed": "Vermell (canceŀla)",
|
||||||
"change_password": "Canvia la contrasenya",
|
"change_password": "Canvia la contrasenya",
|
||||||
"change_password_error": "No s'ha pogut canviar la contrasenya.",
|
"change_password_error": "Hi ha hagut un problema al canviar la teva contrasenya.",
|
||||||
"changed_password": "S'ha canviat la contrasenya correctament!",
|
"changed_password": "S'ha canviat la contrasenya correctament!",
|
||||||
"collapse_subject": "Replega les entrades amb títol",
|
"collapse_subject": "Replega els apunts amb assumpte",
|
||||||
"confirm_new_password": "Confirma la nova contrasenya",
|
"confirm_new_password": "Confirma la nova contrasenya",
|
||||||
"current_avatar": "L'avatar actual",
|
"current_avatar": "El teu avatar actual",
|
||||||
"current_password": "La contrasenya actual",
|
"current_password": "Contrasenya actual",
|
||||||
"current_profile_banner": "El fons de perfil actual",
|
"current_profile_banner": "El fons de perfil actual",
|
||||||
"data_import_export_tab": "Importa o exporta dades",
|
"data_import_export_tab": "Importa dades / exporta",
|
||||||
"default_vis": "Abast per defecte de les entrades",
|
"default_vis": "Visibilitat per defecte dels apunts",
|
||||||
"delete_account": "Esborra el compte",
|
"delete_account": "Esborra el compte",
|
||||||
"delete_account_description": "Esborra permanentment les teves dades i desactiva el teu compte.",
|
"delete_account_description": "Esborra permanentment les teves dades i desactiva el teu compte.",
|
||||||
"delete_account_error": "No s'ha pogut esborrar el compte. Si continua el problema, contacta amb l'administració del node.",
|
"delete_account_error": "Hi ha hagut un problema al esborrar el teu compte. Si continua així, contacta amb l'administrador de l'instància.",
|
||||||
"delete_account_instructions": "Confirma que vols esborrar el compte escrivint la teva contrasenya aquí sota.",
|
"delete_account_instructions": "Escriu la teva contrasenya en el camp de sota per a confirmar esborrar el compte.",
|
||||||
"export_theme": "Desa el tema",
|
"export_theme": "Desa el tema",
|
||||||
"filtering": "Filtres",
|
"filtering": "Filtrant",
|
||||||
"filtering_explanation": "Es silenciaran totes les entrades que continguin aquestes paraules. Separa-les per línies",
|
"filtering_explanation": "Es silenciaran tots els apunts que continguin aquestes paraules, una per línia",
|
||||||
"follow_export": "Exporta la llista de contactes",
|
"follow_export": "Exporta els seguits",
|
||||||
"follow_export_button": "Exporta tots els comptes que segueixes a un fitxer CSV",
|
"follow_export_button": "Exporta els teus seguits a un fitxer CSV",
|
||||||
"follow_export_processing": "S'està processant la petició. Aviat podràs descarregar el fitxer",
|
"follow_export_processing": "S'està processant la petició. Aviat podràs descarregar el fitxer",
|
||||||
"follow_import": "Importa els contactes",
|
"follow_import": "Importa els seguits",
|
||||||
"follow_import_error": "No s'ha pogut importar els contactes",
|
"follow_import_error": "Error al importar els seguidors",
|
||||||
"follows_imported": "S'han importat els contactes. Trigaran una estoneta en ser processats.",
|
"follows_imported": "S'han importat els seguits! Processar-los portarà una estona.",
|
||||||
"foreground": "Primer pla",
|
"foreground": "Primer pla",
|
||||||
"general": "General",
|
"general": "General",
|
||||||
"hide_attachments_in_convo": "Amaga els adjunts en les converses",
|
"hide_attachments_in_convo": "Amaga els adjunts en les converses",
|
||||||
"hide_attachments_in_tl": "Amaga els adjunts en el flux d'entrades",
|
"hide_attachments_in_tl": "Amaga els adjunts en la línia de temps",
|
||||||
"import_followers_from_a_csv_file": "Importa els contactes des d'un fitxer CSV",
|
"import_followers_from_a_csv_file": "Importa els seguits des d'un fitxer CSV",
|
||||||
"import_theme": "Carrega un tema",
|
"import_theme": "Carrega un tema",
|
||||||
"inputRadius": "Caixes d'entrada de text",
|
"inputRadius": "Camps d'entrada",
|
||||||
"instance_default": "(default: {value})",
|
"instance_default": "(default: {value})",
|
||||||
"interfaceLanguage": "Llengua de la interfície",
|
"interfaceLanguage": "Llengua de la interfície",
|
||||||
"invalid_theme_imported": "No s'ha entès l'arxiu carregat perquè no és un tema vàlid de Pleroma. No s'ha fet cap canvi als temes actuals.",
|
"invalid_theme_imported": "L'arxiu seleccionat no és un tema vàlid de Akkoma. No s'ha fet cap canvi al teu tema actual.",
|
||||||
"limited_availability": "No està disponible en aquest navegador",
|
"limited_availability": "No està disponible en el teu navegador",
|
||||||
"links": "Enllaços",
|
"links": "Enllaços",
|
||||||
"lock_account_description": "Restringeix el teu compte només a seguidores aprovades",
|
"lock_account_description": "Restringeix el teu compte només a seguidors aprovats",
|
||||||
"loop_video": "Reprodueix els vídeos en bucle",
|
"loop_video": "Vídeos en bucle",
|
||||||
"loop_video_silent_only": "Reprodueix en bucles només els vídeos sense so (com els \"GIF\" de Mastodon)",
|
"loop_video_silent_only": "Només bucle de vídeos sense so (com els \"GIF\" de Mastodon)",
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
"name_bio": "Nom i presentació",
|
"name_bio": "Nom i bio",
|
||||||
"new_password": "Contrasenya nova",
|
"new_password": "Contrasenya nova",
|
||||||
"notification_visibility": "Notifica'm quan algú",
|
"notification_visibility": "Tipus de notificacions a mostrar",
|
||||||
"notification_visibility_follows": "Comença a seguir-me",
|
"notification_visibility_follows": "Seguits",
|
||||||
"notification_visibility_likes": "Favorits",
|
"notification_visibility_likes": "m'afavoreix",
|
||||||
"notification_visibility_mentions": "Em menciona",
|
"notification_visibility_mentions": "em menciona",
|
||||||
"notification_visibility_repeats": "Republica una entrada meva",
|
"notification_visibility_repeats": "em repeteix",
|
||||||
"no_rich_text_description": "Neteja el formatat de text de totes les entrades",
|
"no_rich_text_description": "Neteja el format de text de tots els apunts",
|
||||||
"nsfw_clickthrough": "Amaga el contingut NSFW darrer d'una imatge clicable",
|
"nsfw_clickthrough": "Amaga els Mèdia sensibles/NSFW",
|
||||||
"oauth_tokens": "Llistats OAuth",
|
"oauth_tokens": "Codis OAuth",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"refresh_token": "Actualitza el token",
|
"refresh_token": "Actualitza el token",
|
||||||
"valid_until": "Vàlid fins",
|
"valid_until": "Vàlid fins",
|
||||||
"revoke_token": "Revocar",
|
"revoke_token": "Revoca",
|
||||||
"panelRadius": "Panells",
|
"panelRadius": "Panells",
|
||||||
"pause_on_unfocused": "Pausa la reproducció en continu quan la pestanya perdi el focus",
|
"pause_on_unfocused": "Pausa quan la pestanya perdi el focus",
|
||||||
"presets": "Temes",
|
"presets": "Temes",
|
||||||
"profile_background": "Fons de pantalla",
|
"profile_background": "Fons del perfil",
|
||||||
"profile_banner": "Fons de perfil",
|
"profile_banner": "Banner del perfil",
|
||||||
"profile_tab": "Perfil",
|
"profile_tab": "Perfil",
|
||||||
"radii_help": "Configura l'arrodoniment de les vores (en píxels)",
|
"radii_help": "Configura l'arrodoniment de les vores (en píxels)",
|
||||||
"replies_in_timeline": "Respostes al flux",
|
"replies_in_timeline": "Respostes en línia de temps",
|
||||||
"reply_visibility_all": "Mostra totes les respostes",
|
"reply_visibility_all": "Mostra totes les respostes",
|
||||||
"reply_visibility_following": "Mostra només les respostes a entrades meves o d'usuàries que jo segueixo",
|
"reply_visibility_following": "Mostra només les respostes dirigides a mi o a usuaris que segueixo",
|
||||||
"reply_visibility_self": "Mostra només les respostes a entrades meves",
|
"reply_visibility_self": "Mostra només les respostes dirigides a mi",
|
||||||
"saving_err": "No s'ha pogut desar la configuració",
|
"saving_err": "Error al desar la configuració",
|
||||||
"saving_ok": "S'ha desat la configuració",
|
"saving_ok": "Configuració desada",
|
||||||
"security_tab": "Seguretat",
|
"security_tab": "Seguretat",
|
||||||
"set_new_avatar": "Canvia l'avatar",
|
"set_new_avatar": "Establir un nou avatar",
|
||||||
"set_new_profile_background": "Canvia el fons de pantalla",
|
"set_new_profile_background": "Canvia el fons del perfil",
|
||||||
"set_new_profile_banner": "Canvia el fons del perfil",
|
"set_new_profile_banner": "Establir un nou banner del perfil",
|
||||||
"settings": "Configuració",
|
"settings": "Configuració",
|
||||||
"stop_gifs": "Anima els GIF només en passar-hi el ratolí per sobre",
|
"stop_gifs": "Anima les imatges animades fins que hi passis el cursor per sobre",
|
||||||
"streaming": "Carrega automàticament entrades noves quan estigui a dalt de tot",
|
"streaming": "Mostra automàticament els nous apunts quan et desplacis a la part superior",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
"theme": "Tema",
|
"theme": "Tema",
|
||||||
"theme_help": "Personalitza els colors del tema. Escriu-los en format RGB hexadecimal (#rrggbb).",
|
"theme_help": "Utilitza els codis de color hex (#rrggbb) per a personalitzar el color del teu tema.",
|
||||||
"tooltipRadius": "Missatges sobreposats",
|
"tooltipRadius": "Globus/alertes",
|
||||||
"user_settings": "Configuració personal",
|
"user_settings": "Configuració d'usuari",
|
||||||
"values": {
|
"values": {
|
||||||
"false": "no",
|
"false": "no",
|
||||||
"true": "sí"
|
"true": "sí"
|
||||||
},
|
},
|
||||||
"show_moderator_badge": "Mostra una insígnia de Moderació en el meu perfil",
|
"show_moderator_badge": "Mostra l'insígnia \"Moderador\" en el meu perfil",
|
||||||
"show_admin_badge": "Mostra una insígnia \"d'Administració\" en el meu perfil",
|
"show_admin_badge": "Mostra l'insígnia \"Administrador\" en el meu perfil",
|
||||||
"hide_followers_description": "No mostris qui m'està seguint",
|
"hide_followers_description": "No mostris qui m'està seguint",
|
||||||
"hide_follows_description": "No mostris a qui segueixo",
|
"hide_follows_description": "No mostris a qui segueixo",
|
||||||
"notification_visibility_emoji_reactions": "Reaccions",
|
"notification_visibility_emoji_reactions": "reacciona",
|
||||||
"new_email": "Nou correu electrònic",
|
"new_email": "Nou correu electrònic",
|
||||||
"profile_fields": {
|
"profile_fields": {
|
||||||
"value": "Contingut",
|
"value": "Contingut",
|
||||||
|
@ -281,69 +281,69 @@
|
||||||
"add_field": "Afegeix un camp",
|
"add_field": "Afegeix un camp",
|
||||||
"label": "Metadades del perfil"
|
"label": "Metadades del perfil"
|
||||||
},
|
},
|
||||||
"mutes_tab": "Silenciaments",
|
"mutes_tab": "Silenciats",
|
||||||
"interface": "Interfície",
|
"interface": "Interfície",
|
||||||
"instance_default_simple": "(per defecte)",
|
"instance_default_simple": "(per defecte)",
|
||||||
"checkboxRadius": "Caselles",
|
"checkboxRadius": "Caselles",
|
||||||
"import_blocks_from_a_csv_file": "Importa bloquejos des d'un arxiu csv",
|
"import_blocks_from_a_csv_file": "Importa bloquejos des d'un arxiu csv",
|
||||||
"hide_post_stats": "Amaga les estadístiques de les entrades (p. ex. el nombre de favorits)",
|
"hide_post_stats": "Amaga les estadístiques dels apunts (p. ex. el número de favorits)",
|
||||||
"use_one_click_nsfw": "Obre els adjunts NSFW amb només un clic",
|
"use_one_click_nsfw": "Obre els adjunts NSFW amb només un clic",
|
||||||
"hide_muted_posts": "Amaga les entrades de comptes silenciats",
|
"hide_muted_posts": "Amaga els apunts de comptes silenciats",
|
||||||
"avatar_size_instruction": "La mida mínima recomanada per la imatge de l'avatar és de 150x150 píxels.",
|
"avatar_size_instruction": "La mida mínima recomanada per les imatges dels avatars és de 150x150 píxels.",
|
||||||
"domain_mutes": "Dominis",
|
"domain_mutes": "Dominis",
|
||||||
"discoverable": "Permet la descoberta d'aquest compte en resultats de cerques i altres serveis",
|
"discoverable": "Permet descobrir aquest compte en resultats de cerques i altres serveis",
|
||||||
"mutes_and_blocks": "Silenciaments i bloquejos",
|
"mutes_and_blocks": "Silenciaments i bloquejos",
|
||||||
"composing": "Composant",
|
"composing": "Composant",
|
||||||
"chatMessageRadius": "Missatge de xat",
|
"chatMessageRadius": "Missatge de xat",
|
||||||
"changed_email": "Correu electrònic canviat amb èxit!",
|
"changed_email": "Correu electrònic canviat amb èxit!",
|
||||||
"change_email_error": "Hi ha hagut un problema al canviar el teu correu electrònic.",
|
"change_email_error": "Hi ha hagut un problema al canviar el teu correu electrònic.",
|
||||||
"change_email": "Canvia el correu electrònic",
|
"change_email": "Canvia el correu electrònic",
|
||||||
"bot": "Aquest és un compte automatitzat",
|
"bot": "Aquest és un compte bot",
|
||||||
"blocks_tab": "Bloquejos",
|
"blocks_tab": "Bloquejos",
|
||||||
"blocks_imported": "Bloquejos importats! Processar-los pot trigar una mica.",
|
"blocks_imported": "Bloquejos importats! Processar-los pot trigar una mica.",
|
||||||
"block_import_error": "Error al importar bloquejos",
|
"block_import_error": "Error al importar bloquejos",
|
||||||
"block_import": "Importa bloquejos",
|
"block_import": "Importa bloquejos",
|
||||||
"block_export_button": "Exporta els teus bloquejos a un arxiu csv",
|
"block_export_button": "Exporta els teus bloquejos a un arxiu csv",
|
||||||
"block_export": "Exporta bloquejos",
|
"block_export": "Exporta bloquejos",
|
||||||
"allow_following_move": "Permet el seguiment automàtic quan un compte a qui seguim es mou",
|
"allow_following_move": "Permet el seguiment automàtic quan un compte a qui seguim es mogui",
|
||||||
"mfa": {
|
"mfa": {
|
||||||
"scan": {
|
"scan": {
|
||||||
"secret_code": "Clau",
|
"secret_code": "Clau",
|
||||||
"title": "Escanejar",
|
"title": "Escanejar",
|
||||||
"desc": "S'està usant l'aplicació two-factor, escaneja aquest codi QR o introdueix la clau de text:"
|
"desc": "S'està usant la teva aplicació de dos factors, escaneja aquest codi QR o introdueix la clau de text:"
|
||||||
},
|
},
|
||||||
"authentication_methods": "Mètodes d'autenticació",
|
"authentication_methods": "Mètodes d'autenticació",
|
||||||
"waiting_a_recovery_codes": "Rebent còpies de seguretat dels codis…",
|
"waiting_a_recovery_codes": "Rebent còpies de seguretat dels codis…",
|
||||||
"recovery_codes": "Codis de recuperació.",
|
"recovery_codes": "Codis de recuperació.",
|
||||||
"warning_of_generate_new_codes": "Quan generes nous codis de recuperació, els antics ja no funcionaran més.",
|
"warning_of_generate_new_codes": "Quan generes nous codis de recuperació, els teus antics ja no funcionaran més.",
|
||||||
"generate_new_recovery_codes": "Genera nous codis de recuperació",
|
"generate_new_recovery_codes": "Genera nous codis de recuperació",
|
||||||
"otp": "OTP",
|
"otp": "OTP",
|
||||||
"confirm_and_enable": "Confirmar i habilitar OTP",
|
"confirm_and_enable": "Confirma i habilita OTP",
|
||||||
"recovery_codes_warning": "Anote els codis o guarda'ls en un lloc segur, o no els veuràs una altra volta. Si perds l'accés a la teua aplicació 2FA i els codis de recuperació, no podràs accedir al compte.",
|
"recovery_codes_warning": "Anota els codis o desa'ls en un lloc segur - si no ho fas, no els podràs veure mai més . Si perds l'accés a la teva aplicació 2FA i als codis de recuperació, no podràs accedir al compte.",
|
||||||
"title": "Autenticació de dos factors",
|
"title": "Autenticació de dos factors",
|
||||||
"setup_otp": "Configurar OTP",
|
"setup_otp": "Configurar OTP",
|
||||||
"wait_pre_setup_otp": "preconfiguració OTP",
|
"wait_pre_setup_otp": "preconfiguració OTP",
|
||||||
"verify": {
|
"verify": {
|
||||||
"desc": "Per habilitar l'autenticació two-factor, introdueix el codi des de la teva aplicació two-factor:"
|
"desc": "Per a habilitar l'autenticació de dos factors, introdueix el codi des de la teva aplicació de dos factors:"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enter_current_password_to_confirm": "Posar la contrasenya actual per confirmar la teva identitat",
|
"enter_current_password_to_confirm": "Posa la teva contrasenya actual per a confirmar la teva identitat",
|
||||||
"security": "Seguretat",
|
"security": "Seguretat",
|
||||||
"app_name": "Nom de l'aplicació",
|
"app_name": "Nom de l'aplicació",
|
||||||
"subject_line_mastodon": "Com a mastodon: copiar com és",
|
"subject_line_mastodon": "Com a mastodon: copiar com és",
|
||||||
"mute_export_button": "Exportar silenciats a un fitxer csv",
|
"mute_export_button": "Exportar els teus silenciats a un fitxer csv",
|
||||||
"mute_import_error": "Error al importar silenciats",
|
"mute_import_error": "Error al importar silenciats",
|
||||||
"mutes_imported": "Silenciats importats! Processar-los portarà una estona.",
|
"mutes_imported": "Silenciats importats! Processar-los portarà una estona.",
|
||||||
"import_mutes_from_a_csv_file": "Importar silenciats des d'un fitxer csv",
|
"import_mutes_from_a_csv_file": "Importar silenciats des d'un fitxer csv",
|
||||||
"word_filter": "Filtre de paraules",
|
"word_filter": "Filtre de paraules",
|
||||||
"hide_media_previews": "Ocultar les vistes prèvies multimèdia",
|
"hide_media_previews": "Ocultar les vistes prèvies multimèdia",
|
||||||
"hide_filtered_statuses": "Amagar estats filtrats",
|
"hide_filtered_statuses": "Amaga apunts filtrats",
|
||||||
"play_videos_in_modal": "Reproduir vídeos en un marc emergent",
|
"play_videos_in_modal": "Reproduir vídeos en un marc emergent",
|
||||||
"file_export_import": {
|
"file_export_import": {
|
||||||
"errors": {
|
"errors": {
|
||||||
"invalid_file": "El fitxer seleccionat no és vàlid com a còpia de seguretat de la configuració. No s'ha realitzat cap canvi.",
|
"invalid_file": "El fitxer seleccionat no és suportat per Akkoma com a còpia de seguretat de la configuració. No s'ha realitzat cap canvi.",
|
||||||
"file_too_new": "Versió important incompatible: {fileMajor}, aquest PleromaFE (configuració versió {feMajor}) és massa antiga per gestionar-lo",
|
"file_too_new": "Versió important incompatible: {fileMajor}, aquest PleromaFE (configuració versió {feMajor}) és massa antiga per gestionar-lo",
|
||||||
"file_too_old": "Versió important incompatible: {fileMajor}, la versió del fitxer és massa antiga i no està implementada (s'ha establert un mínim ver. {feMajor})",
|
"file_too_old": "Versió important incompatible: {fileMajor}, la versió del fitxer és massa antiga i no està suportada (min. set. ver. {feMajor})",
|
||||||
"file_slightly_new": "La versió menor del fitxer és diferent, alguns paràmetres podrien no carregar-se"
|
"file_slightly_new": "La versió menor del fitxer és diferent, alguns paràmetres podrien no carregar-se"
|
||||||
},
|
},
|
||||||
"backup_settings": "Còpia de seguretat de la configuració a un fitxer",
|
"backup_settings": "Còpia de seguretat de la configuració a un fitxer",
|
||||||
|
@ -352,42 +352,42 @@
|
||||||
"backup_restore": "Còpia de seguretat de la configuració"
|
"backup_restore": "Còpia de seguretat de la configuració"
|
||||||
},
|
},
|
||||||
"user_mutes": "Usuaris",
|
"user_mutes": "Usuaris",
|
||||||
"subject_line_email": "Com a l'email: \"re: tema\"",
|
"subject_line_email": "Com a l'email: \"re: assumpte\"",
|
||||||
"search_user_to_block": "Busca a qui vols bloquejar",
|
"search_user_to_block": "Busca a qui vols bloquejar",
|
||||||
"save": "Guardar els canvis",
|
"save": "Desar els canvis",
|
||||||
"use_contain_fit": "No retallar els adjunts en miniatures",
|
"use_contain_fit": "No retallar els adjunts en miniatures",
|
||||||
"reset_profile_background": "Restablir fons del perfil",
|
"reset_profile_background": "Restablir fons del perfil",
|
||||||
"reset_profile_banner": "Restablir banner del perfil",
|
"reset_profile_banner": "Restablir banner del perfil",
|
||||||
"emoji_reactions_on_timeline": "Mostrar reaccions emoji al flux",
|
"emoji_reactions_on_timeline": "Mostra reaccions emoji en la línia de temps",
|
||||||
"max_thumbnails": "Quantitat màxima de miniatures per publicació",
|
"max_thumbnails": "Quantitat màxima de miniatures per apunt (buit = sense limit)",
|
||||||
"hide_user_stats": "Amagar les estadístiques de l'usuari (p. ex. el nombre de seguidors)",
|
"hide_user_stats": "Amaga les estadístiques de l'usuari (p. ex. el número de seguidors)",
|
||||||
"reset_banner_confirm": "Realment vols restablir el banner?",
|
"reset_banner_confirm": "Realment vols restablir el banner?",
|
||||||
"reset_background_confirm": "Realment vols restablir el fons del perfil?",
|
"reset_background_confirm": "Realment vols restablir el fons?",
|
||||||
"subject_input_always_show": "Sempre mostrar el camp del tema",
|
"subject_input_always_show": "Sempre mostrar el camp del assumpte",
|
||||||
"subject_line_noop": "No copiar",
|
"subject_line_noop": "No copiar",
|
||||||
"subject_line_behavior": "Copiar el tema a les respostes",
|
"subject_line_behavior": "Copiar l'assumpte en les respostes",
|
||||||
"search_user_to_mute": "Busca a qui vols silenciar",
|
"search_user_to_mute": "Busca a qui vols silenciar",
|
||||||
"mute_export": "Exportar silenciats",
|
"mute_export": "Exportar silenciats",
|
||||||
"scope_copy": "Copiar visibilitat quan contestes (En els missatges directes sempre es copia)",
|
"scope_copy": "Copiar visibilitat quan responguis (en els missatges directes sempre es copia)",
|
||||||
"reset_avatar": "Restablir avatar",
|
"reset_avatar": "Restablir l'avatar",
|
||||||
"right_sidebar": "Mostrar barra lateral a la dreta",
|
"right_sidebar": "Ordre invers de les columnes",
|
||||||
"no_blocks": "No hi han bloquejats",
|
"no_blocks": "No hi han bloquejats",
|
||||||
"no_mutes": "No hi han silenciats",
|
"no_mutes": "No hi han silenciats",
|
||||||
"hide_follows_count_description": "No mostrar el nombre de comptes que segueixo",
|
"hide_follows_count_description": "No mostrar el número dels meus seguits",
|
||||||
"mute_import": "Importar silenciats",
|
"mute_import": "Importar silenciats",
|
||||||
"hide_all_muted_posts": "Ocultar publicacions silenciades",
|
"hide_all_muted_posts": "Ocultar apunts silenciades",
|
||||||
"hide_wallpaper": "Amagar el fons de la instància",
|
"hide_wallpaper": "Amagar el fons de la instància",
|
||||||
"notification_visibility_moves": "Usuari Migrat",
|
"notification_visibility_moves": "es mou",
|
||||||
"reply_visibility_following_short": "Mostrar respostes als meus seguidors",
|
"reply_visibility_following_short": "Mostrar respostes als meus seguits",
|
||||||
"reply_visibility_self_short": "Mostrar respostes només a un mateix",
|
"reply_visibility_self_short": "Mostrar només respostes a mi mateix",
|
||||||
"autohide_floating_post_button": "Ocultar automàticament el botó 'Nova Publicació' (mòbil)",
|
"autohide_floating_post_button": "Ocultar automàticament el botó 'Nou Apunt' (mòbil)",
|
||||||
"minimal_scopes_mode": "Minimitzar les opcions de visibilitat de la publicació",
|
"minimal_scopes_mode": "Minimitzar les opcions de selecció del abast del apunt",
|
||||||
"sensitive_by_default": "Marcar publicacions com a sensibles per defecte",
|
"sensitive_by_default": "Marcar apunts com a sensibles per defecte",
|
||||||
"useStreamingApi": "Rebre publicacions i notificacions en temps real",
|
"useStreamingApi": "Rebre apunts i notificacions en temps real",
|
||||||
"hide_isp": "Ocultar el panell especific de la instància",
|
"hide_isp": "Amaga el panell especific de la instància",
|
||||||
"preload_images": "Precarregar les imatges",
|
"preload_images": "Precarregar les imatges",
|
||||||
"setting_changed": "La configuració és diferent a la predeterminada",
|
"setting_changed": "La configuració és diferent a la predeterminada",
|
||||||
"hide_followers_count_description": "No mostrar el nombre de seguidors",
|
"hide_followers_count_description": "No mostrar el número de seguidors",
|
||||||
"reset_avatar_confirm": "Realment vols restablir l'avatar?",
|
"reset_avatar_confirm": "Realment vols restablir l'avatar?",
|
||||||
"accent": "Accent",
|
"accent": "Accent",
|
||||||
"useStreamingApiWarning": "És genial emprar-lo. Si es trenca, refresca, suposo?",
|
"useStreamingApiWarning": "És genial emprar-lo. Si es trenca, refresca, suposo?",
|
||||||
|
@ -397,10 +397,10 @@
|
||||||
"size": "Mida (en píxels)",
|
"size": "Mida (en píxels)",
|
||||||
"custom": "Personalitza",
|
"custom": "Personalitza",
|
||||||
"_tab_label": "Fonts",
|
"_tab_label": "Fonts",
|
||||||
"help": "Selecciona la font per als elements de la interfície. Per a \"personalitzat\" deus escriure el nom de la font exactament com apareix al sistema.",
|
"help": "Selecciona la font per als elements de la interfície. Per a \"personalitzat\" has d'escriure el nom de la font exactament com apareix al sistema.",
|
||||||
"components": {
|
"components": {
|
||||||
"post": "Text de les publicacions",
|
"post": "Text dels apunts",
|
||||||
"postCode": "Text monoespai en publicació (text enriquit)",
|
"postCode": "Text mono-espai en un apunt (text enriquit)",
|
||||||
"input": "Camps d'entrada",
|
"input": "Camps d'entrada",
|
||||||
"interface": "Interfície"
|
"interface": "Interfície"
|
||||||
},
|
},
|
||||||
|
@ -418,19 +418,19 @@
|
||||||
"checkbox": "He llegit els termes i condicions",
|
"checkbox": "He llegit els termes i condicions",
|
||||||
"link": "un bonic enllaç",
|
"link": "un bonic enllaç",
|
||||||
"fine_print": "Llegiu el nostre {0} per no aprendre res útil!",
|
"fine_print": "Llegiu el nostre {0} per no aprendre res útil!",
|
||||||
"text": "Un grapat més de {0} i {1}"
|
"text": "Un grapat més {0} i {1}"
|
||||||
},
|
},
|
||||||
"shadows": {
|
"shadows": {
|
||||||
"spread": "Difon",
|
"spread": "Difon",
|
||||||
"filter_hint": {
|
"filter_hint": {
|
||||||
"drop_shadow_syntax": "{0} no suporta el paràmetre {1} i la paraula clau {2}.",
|
"drop_shadow_syntax": "{0} no suporta el paràmetre {1} i la paraula clau {2}.",
|
||||||
"avatar_inset": "Tingues en compte que combinar ombres interiors i no interiors als avatars podria donar resultats inesperats amb avatars transparents.",
|
"avatar_inset": "Tingues en compte que combinar ombres interiors i no interiors als avatars podria donar resultats inesperats amb avatars transparents.",
|
||||||
"inset_classic": "Les ombres interiors estaran usant {0}",
|
"inset_classic": "Les ombres interiors usaran {0}",
|
||||||
"always_drop_shadow": "Advertència, aquesta ombra sempre utilitza {0} quan el navegador ho suporta.",
|
"always_drop_shadow": "Advertència, aquesta ombra sempre utilitza {0} quan el navegador ho suporta.",
|
||||||
"spread_zero": "Ombres amb propagació > 0 apareixeran com si estigueren posades a zero"
|
"spread_zero": "Ombres amb propagació > 0 apareixeran com si estigueren posades a zero"
|
||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"popup": "Texts i finestres emergents (popups & tooltips)",
|
"popup": "Globus i finestres emergents",
|
||||||
"panel": "Panell",
|
"panel": "Panell",
|
||||||
"panelHeader": "Capçalera del panell",
|
"panelHeader": "Capçalera del panell",
|
||||||
"avatar": "Avatar de l'usuari (en vista de perfil)",
|
"avatar": "Avatar de l'usuari (en vista de perfil)",
|
||||||
|
@ -438,8 +438,8 @@
|
||||||
"buttonHover": "Botó (surant)",
|
"buttonHover": "Botó (surant)",
|
||||||
"buttonPressed": "Botó (pressionat)",
|
"buttonPressed": "Botó (pressionat)",
|
||||||
"topBar": "Barra superior",
|
"topBar": "Barra superior",
|
||||||
"buttonPressedHover": "Botó (surant i pressionat)",
|
"buttonPressedHover": "Botó (pressionat i surant)",
|
||||||
"avatarStatus": "Avatar de l'usuari (en vista de publicació)",
|
"avatarStatus": "Avatar de l'usuari (en vista de apunt)",
|
||||||
"button": "Botó"
|
"button": "Botó"
|
||||||
},
|
},
|
||||||
"hintV3": "per a les ombres també pots usar la notació {0} per a utilitzar un altre espai de color.",
|
"hintV3": "per a les ombres també pots usar la notació {0} per a utilitzar un altre espai de color.",
|
||||||
|
@ -456,24 +456,24 @@
|
||||||
"future_version_imported": "El fitxer importat es va crear per a una versió del front-end més recent.",
|
"future_version_imported": "El fitxer importat es va crear per a una versió del front-end més recent.",
|
||||||
"migration_snapshot_ok": "Per a estar segurs, s'ha carregat la instantània del tema. Pots intentar carregar les dades del tema.",
|
"migration_snapshot_ok": "Per a estar segurs, s'ha carregat la instantània del tema. Pots intentar carregar les dades del tema.",
|
||||||
"migration_napshot_gone": "Per alguna raó, faltava la instantània, algunes coses podrien veure's diferents del que recordes.",
|
"migration_napshot_gone": "Per alguna raó, faltava la instantània, algunes coses podrien veure's diferents del que recordes.",
|
||||||
"snapshot_source_mismatch": "Conflicte de versions: probablement el front-end s'ha revertit i actualitzat una altra volta, si has canviat el tema en una versió anterior, segurament vols utilitzar la versió antiga; d'altra banda utilitza la nova versió.",
|
"snapshot_source_mismatch": "Conflicte de versions: probablement el front-end s'ha revertit i actualitzat de nou, si has canviat el tema en una versió anterior, segurament vols utilitzar la versió antiga; d'altra banda utilitza la nova versió.",
|
||||||
"v2_imported": "El fitxer que has importat va ser creat per a un front-end més antic. Intentem maximitzar la compatibilitat, però podrien haver inconsistències.",
|
"v2_imported": "El fitxer que has importat va ser creat per a un front-end més antic. Intentem maximitzar la compatibilitat, però podrien haver inconsistències.",
|
||||||
"fe_upgraded": "El motor de temes de PleromaFE es va actualitzar després de l'actualització de la versió.",
|
"fe_upgraded": "El motor de temes de PleromaFE es va actualitzar després de l'actualització de la versió.",
|
||||||
"snapshot_missing": "No hi havia cap instantània del tema al fitxer, per tant podria veure's diferent del previst originalment.",
|
"snapshot_missing": "No hi havia cap instantània del tema al fitxer, per tant podria veure's diferent del previst originalment.",
|
||||||
"upgraded_from_v2": "PleromaFE s'ha actualitzat, el tema pot veure's un poc diferent de com recordes.",
|
"upgraded_from_v2": "PleromaFE s'ha actualitzat, el tema es pot veure una mica diferent de com el recordes.",
|
||||||
"fe_downgraded": "Versió de PleromaFE revertida.",
|
"fe_downgraded": "Versió de PleromaFE revertida.",
|
||||||
"older_version_imported": "El fitxer que has importat va ser creat en una versió del front-end més antiga.",
|
"older_version_imported": "El fitxer que has importat va ser creat en una versió del front-end més antiga.",
|
||||||
"snapshot_present": "S'ha carregat la instantània del tema, de manera que tots els valors estan sobreescrits. En canvi, podeu carregar les dades reals del tema."
|
"snapshot_present": "S'ha carregat la instantània del tema, de manera que tots els valors estan sobreescrits. En canvi, podeu carregar les dades reals del tema."
|
||||||
},
|
},
|
||||||
"keep_as_is": "Mantindre com està",
|
"keep_as_is": "Mantindre com està",
|
||||||
"save_load_hint": "Les opcions \"Mantindre\" conserven les opcions configurades actualment al seleccionar o carregar temes, també emmagatzema aquestes opcions quan s'exporta un tema. Quan es desactiven totes les caselles de verificació, el tema exportat ho guardarà tot.",
|
"save_load_hint": "Les opcions \"Mantindre\" conserven les opcions configurades actualment al seleccionar o carregar temes, també emmagatzema aquestes opcions quan s'exporta un tema. Quan es desactiven totes les caselles de verificació, exportar el tema ho desarà tot.",
|
||||||
"keep_color": "Mantindre colors",
|
"keep_color": "Mantindre colors",
|
||||||
"keep_opacity": "Mantindre opacitat",
|
"keep_opacity": "Mantindre opacitat",
|
||||||
"keep_shadows": "Mantindre ombres",
|
"keep_shadows": "Mantindre ombres",
|
||||||
"keep_fonts": "Mantindre fonts",
|
"keep_fonts": "Mantindre fonts",
|
||||||
"keep_roundness": "Mantindre rodoneses",
|
"keep_roundness": "Mantindre rodoneses",
|
||||||
"clear_all": "Netejar tot",
|
"clear_all": "Netejar tot",
|
||||||
"reset": "Reinciar",
|
"reset": "Reiniciar",
|
||||||
"load_theme": "Carregar tema",
|
"load_theme": "Carregar tema",
|
||||||
"use_source": "Nova versió",
|
"use_source": "Nova versió",
|
||||||
"clear_opacity": "Netejar opacitat"
|
"clear_opacity": "Netejar opacitat"
|
||||||
|
@ -482,9 +482,9 @@
|
||||||
"contrast": {
|
"contrast": {
|
||||||
"hint": "El ràtio de contrast és {ratio}. {level} {context}",
|
"hint": "El ràtio de contrast és {ratio}. {level} {context}",
|
||||||
"level": {
|
"level": {
|
||||||
"bad": "no compleix amb cap pauta d'accecibilitat",
|
"bad": "no compleix amb cap pauta d'accessibilitat",
|
||||||
"aaa": "Compleix amb el nivell AA (recomanat)",
|
"aaa": "Compleix amb la guia del nivell AA (recomanat)",
|
||||||
"aa": "Compleix amb el nivell AA (mínim)"
|
"aa": "Compleix amb la guia del nivell AA (mínim)"
|
||||||
},
|
},
|
||||||
"context": {
|
"context": {
|
||||||
"18pt": "per a textos grans (+18pt)",
|
"18pt": "per a textos grans (+18pt)",
|
||||||
|
@ -501,8 +501,8 @@
|
||||||
"pressed": "Pressionat",
|
"pressed": "Pressionat",
|
||||||
"chat": {
|
"chat": {
|
||||||
"outgoing": "Eixint",
|
"outgoing": "Eixint",
|
||||||
"border": "Borde",
|
"border": "Vora",
|
||||||
"incoming": "Entrants"
|
"incoming": "Entrant"
|
||||||
},
|
},
|
||||||
"borders": "Bordes",
|
"borders": "Bordes",
|
||||||
"panel_header": "Capçalera del panell",
|
"panel_header": "Capçalera del panell",
|
||||||
|
@ -512,8 +512,8 @@
|
||||||
"toggled": "Commutat",
|
"toggled": "Commutat",
|
||||||
"alert": "Fons d'alertes",
|
"alert": "Fons d'alertes",
|
||||||
"alert_error": "Error",
|
"alert_error": "Error",
|
||||||
"alert_warning": "Precaució",
|
"alert_warning": "Avís",
|
||||||
"post": "Publicacions/Biografies d'usuaris",
|
"post": "Apunts/Bio d'usuari",
|
||||||
"badge_notification": "Notificacions",
|
"badge_notification": "Notificacions",
|
||||||
"selectedMenu": "Element del menú seleccionat",
|
"selectedMenu": "Element del menú seleccionat",
|
||||||
"tabs": "Pestanyes",
|
"tabs": "Pestanyes",
|
||||||
|
@ -524,7 +524,7 @@
|
||||||
"highlight": "Elements destacats",
|
"highlight": "Elements destacats",
|
||||||
"disabled": "Deshabilitat",
|
"disabled": "Deshabilitat",
|
||||||
"icons": "Icones",
|
"icons": "Icones",
|
||||||
"selectedPost": "Publicació seleccionada",
|
"selectedPost": "Apunt seleccionat",
|
||||||
"underlay": "Subratllat"
|
"underlay": "Subratllat"
|
||||||
},
|
},
|
||||||
"common_colors": {
|
"common_colors": {
|
||||||
|
@ -538,32 +538,32 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version": {
|
"version": {
|
||||||
"frontend_version": "Versió \"Frontend\"",
|
"frontend_version": "Versió del \"Frontend\"",
|
||||||
"backend_version": "Versió \"backend\"",
|
"backend_version": "Versió del \"backend\"",
|
||||||
"title": "Versió"
|
"title": "Versió"
|
||||||
},
|
},
|
||||||
"theme_help_v2_1": "També pots anular alguns components de color i opacitat activant la casella. Usa el botó \"Esborrar tot\" per esborrar totes les anulacions.",
|
"theme_help_v2_1": "També pots anul·lar els colors d'alguns components i la seva opacitat activant la casella. Usa el botó \"Esborrar tot\" per esborrar totes les anul·lacions.",
|
||||||
"type_domains_to_mute": "Buscar dominis per a silenciar",
|
"type_domains_to_mute": "Buscar dominis per a silenciar",
|
||||||
"greentext": "Text verd (meme arrows)",
|
"greentext": "Text verd (meme arrows)",
|
||||||
"fun": "Divertit",
|
"fun": "Divertit",
|
||||||
"notification_setting_filters": "Filtres",
|
"notification_setting_filters": "Filtres",
|
||||||
"virtual_scrolling": "Optimitzar la representació del flux",
|
"virtual_scrolling": "Optimitza el renderitzat de la línia de temps",
|
||||||
"notification_setting_block_from_strangers": "Bloqueja les notificacions dels usuaris que no segueixes",
|
"notification_setting_block_from_strangers": "Bloqueja les notificacions dels usuaris que no segueixes",
|
||||||
"enable_web_push_notifications": "Habilitar notificacions del navegador",
|
"enable_web_push_notifications": "Habilitar notificacions del navegador",
|
||||||
"notification_blocks": "Bloquejar a un usuari para totes les notificacions i també les cancel·la.",
|
"notification_blocks": "Bloquejar a un usuari para totes les notificacions i cancel·la la subscripció.",
|
||||||
"more_settings": "Més opcions",
|
"more_settings": "Més opcions",
|
||||||
"notification_setting_privacy": "Privacitat",
|
"notification_setting_privacy": "Privacitat",
|
||||||
"upload_a_photo": "Pujar una foto",
|
"upload_a_photo": "Pujar una foto",
|
||||||
"notification_setting_hide_notification_contents": "Amagar el remitent i els continguts de les notificacions push",
|
"notification_setting_hide_notification_contents": "Amagar el remitent i els continguts de les notificacions push",
|
||||||
"notifications": "Notificacions",
|
"notifications": "Notificacions",
|
||||||
"notification_mutes": "Per a deixar de rebre notificacions d'un usuari en concret, silencia'l-ho.",
|
"notification_mutes": "Per a deixar de rebre notificacions d'un usuari en concret, silencia'l.",
|
||||||
"theme_help_v2_2": "Les icones per baix d'algunes entrades són indicadors del contrast del fons/text, desplaça el ratolí per a més informació. Tingues en compte que quan s'utilitzen indicadors de contrast de transparència es mostra el pitjor cas possible.",
|
"theme_help_v2_2": "Les icones per sota d'algunes entrades són indicadors del contrast del fons/text, posiciona el ratolí al damunt per a més informació. Tingues en compte que quan s'utilitzen indicadors de contrast de transparència es mostra el pitjor cas possible.",
|
||||||
"hide_shoutbox": "Oculta la casella de gàbia de grills",
|
"hide_shoutbox": "Amaga la casella de gàbia de grills",
|
||||||
"always_show_post_button": "Mostra sempre el botó flotant de publicació nova",
|
"always_show_post_button": "Mostra sempre el botó flotant d'Apunt Nou",
|
||||||
"pad_emoji": "Acompanya els emojis amb espais en afegir des del selector",
|
"pad_emoji": "Acompanya els emojis amb espais al afegir-los des del selector",
|
||||||
"mentions_new_style": "Enllaços d'esment més elegants",
|
"mentions_new_style": "Enllaços d'esment més elegants",
|
||||||
"mentions_new_place": "Posa les mencions en una línia separada",
|
"mentions_new_place": "Posa les mencions en una línia separada",
|
||||||
"post_status_content_type": "Format de publicació",
|
"post_status_content_type": "Tipus de contingut del apunt",
|
||||||
"expert_mode": "Mostra avançat",
|
"expert_mode": "Mostra avançat",
|
||||||
"setting_server_side": "Aquest ajust està lligat al teu perfil i afectarà a totes les sessions i clients",
|
"setting_server_side": "Aquest ajust està lligat al teu perfil i afectarà a totes les sessions i clients",
|
||||||
"account_backup": "Copia de seguretat del compte",
|
"account_backup": "Copia de seguretat del compte",
|
||||||
|
@ -572,7 +572,7 @@
|
||||||
"account_alias": "Àlies del compte",
|
"account_alias": "Àlies del compte",
|
||||||
"list_aliases_error": "Error al obtenir els àlies: {error}",
|
"list_aliases_error": "Error al obtenir els àlies: {error}",
|
||||||
"move_account_notes": "Si vols moure el compte a un altre lloc has d'anar a aquest altre compte i afegir un àlies que apunti a aquest.",
|
"move_account_notes": "Si vols moure el compte a un altre lloc has d'anar a aquest altre compte i afegir un àlies que apunti a aquest.",
|
||||||
"hide_wordfiltered_statuses": "Amaga publicacions filtrades per paraules",
|
"hide_wordfiltered_statuses": "Amaga apunts filtrats per paraules",
|
||||||
"account_privacy": "Privacitat",
|
"account_privacy": "Privacitat",
|
||||||
"hide_favorites_description": "No mostrar la llista dels meus favorits (la gent seguirà sent notificada)",
|
"hide_favorites_description": "No mostrar la llista dels meus favorits (la gent seguirà sent notificada)",
|
||||||
"mascot": "Mascota de Mastodon FE",
|
"mascot": "Mascota de Mastodon FE",
|
||||||
|
@ -585,7 +585,7 @@
|
||||||
"mention_link_show_tooltip": "Mostra noms d'usuari complet com a globus per a usuaris remots",
|
"mention_link_show_tooltip": "Mostra noms d'usuari complet com a globus per a usuaris remots",
|
||||||
"notification_setting_hide_if_cw": "Amaga els continguts de les publicacions push si son sota un Avís de Contingut",
|
"notification_setting_hide_if_cw": "Amaga els continguts de les publicacions push si son sota un Avís de Contingut",
|
||||||
"mute_bot_posts": "Silencia publicacions de bot",
|
"mute_bot_posts": "Silencia publicacions de bot",
|
||||||
"post_look_feel": "Aspecte i Sensació de les Publicacions",
|
"post_look_feel": "Aspecte i Sensació dels apunts",
|
||||||
"mention_links": "Enllaços de mencions",
|
"mention_links": "Enllaços de mencions",
|
||||||
"email_language": "Llengua per a rebre correus des d'el servidor",
|
"email_language": "Llengua per a rebre correus des d'el servidor",
|
||||||
"wordfilter": "Filtre de paraules",
|
"wordfilter": "Filtre de paraules",
|
||||||
|
@ -594,7 +594,7 @@
|
||||||
"remove_backup": "Treure",
|
"remove_backup": "Treure",
|
||||||
"list_backups_error": "Error al recuperar la llista de copies de seguretat: {error}",
|
"list_backups_error": "Error al recuperar la llista de copies de seguretat: {error}",
|
||||||
"add_backup": "Crea una nova copia de seguretat",
|
"add_backup": "Crea una nova copia de seguretat",
|
||||||
"added_backup": "Afegida una nova còpia de seguretat nova.",
|
"added_backup": "Afegida una nova còpia de seguretat.",
|
||||||
"add_backup_error": "Error al afegir una nova còpia de seguretat: {error}",
|
"add_backup_error": "Error al afegir una nova còpia de seguretat: {error}",
|
||||||
"current_mascot": "La teva mascota actual",
|
"current_mascot": "La teva mascota actual",
|
||||||
"account_alias_table_head": "Àlies",
|
"account_alias_table_head": "Àlies",
|
||||||
|
@ -607,11 +607,11 @@
|
||||||
"move_account_target": "Compte destí (p.ex. {example})",
|
"move_account_target": "Compte destí (p.ex. {example})",
|
||||||
"moved_account": "El compte s'ha mogut.",
|
"moved_account": "El compte s'ha mogut.",
|
||||||
"move_account_error": "Error al moure el compte: {error}",
|
"move_account_error": "Error al moure el compte: {error}",
|
||||||
"hide_bot_indication": "Amaga l'indicació de bot en las publicacions",
|
"hide_bot_indication": "Amaga l'indicació de bot en els apunts",
|
||||||
"hide_muted_threads": "Amaga fils silenciats",
|
"hide_muted_threads": "Amaga fils silenciats",
|
||||||
"posts": "Publicacions",
|
"posts": "Apunts",
|
||||||
"user_profiles": "Perfils d'usuari",
|
"user_profiles": "Perfils d'usuari",
|
||||||
"notification_visibility_polls": "Terminis de les enquestes on has votat",
|
"notification_visibility_polls": "finalitza una enquesta on hi has votat",
|
||||||
"conversation_display": "Estil de visualització de la conversa",
|
"conversation_display": "Estil de visualització de la conversa",
|
||||||
"conversation_display_tree": "Estil d'arbre",
|
"conversation_display_tree": "Estil d'arbre",
|
||||||
"show_scrollbars": "Mostra les barres de desplaçament de la columna lateral",
|
"show_scrollbars": "Mostra les barres de desplaçament de la columna lateral",
|
||||||
|
@ -631,41 +631,41 @@
|
||||||
"mention_link_display_full": "sempre com a noms complets (p. ex. {'@'}maria{'@'}exemple.cat)",
|
"mention_link_display_full": "sempre com a noms complets (p. ex. {'@'}maria{'@'}exemple.cat)",
|
||||||
"mention_link_show_avatar": "Mostra l'avatar del usuari sota l'enllaç",
|
"mention_link_show_avatar": "Mostra l'avatar del usuari sota l'enllaç",
|
||||||
"mention_link_fade_domain": "Dominis esvaïts (p. ex. {'@'}exemple.cat a {'@'}joan{'@'}exemple.cat)",
|
"mention_link_fade_domain": "Dominis esvaïts (p. ex. {'@'}exemple.cat a {'@'}joan{'@'}exemple.cat)",
|
||||||
"mention_link_bolden_you": "Destaca mencions per tu quan siguis mencionat",
|
"mention_link_bolden_you": "Destaca mencions per tu quan et mencionin",
|
||||||
"show_yous": "Mostra (Tu)s"
|
"show_yous": "Mostra (Tu)s"
|
||||||
},
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"now": "ara mateix",
|
"now": "ara mateix",
|
||||||
"now_short": "ara mateix",
|
"now_short": "ara mateix",
|
||||||
"in_future": "in {0}",
|
"in_future": "en {0}",
|
||||||
"in_past": "fa {0}",
|
"in_past": "fa {0}",
|
||||||
"unit": {
|
"unit": {
|
||||||
"day": "{0} dia",
|
"day": "{0} dia",
|
||||||
"days": "{0} dies",
|
"days": "{0} dia | {0} dies",
|
||||||
"day_short": "{0} dia",
|
"day_short": "{0} dia",
|
||||||
"days_short": "{0} dies",
|
"days_short": "{0}d",
|
||||||
"hour": "{0} hora",
|
"hour": "{0} hora",
|
||||||
"hours": "{0} hores",
|
"hours": "{0} hora | {0} hores",
|
||||||
"hour_short": "{0}h",
|
"hour_short": "{0}h",
|
||||||
"hours_short": "{0}h",
|
"hours_short": "{0}h",
|
||||||
"minute": "{0} minute",
|
"minute": "{0} minute",
|
||||||
"minutes": "{0} minutes",
|
"minutes": "{0} minuts | {0} minuts",
|
||||||
"minute_short": "{0}min",
|
"minute_short": "{0}min",
|
||||||
"minutes_short": "{0}min",
|
"minutes_short": "{0}min",
|
||||||
"month": "{0} mes",
|
"month": "{0} mes",
|
||||||
"months": "{0} mesos",
|
"months": "{0} mes | {0} mesos",
|
||||||
"month_short": "{0} mes",
|
"month_short": "{0} mes",
|
||||||
"months_short": "{0} mesos",
|
"months_short": "{0}mes",
|
||||||
"second": "{0} segon",
|
"second": "{0} segon",
|
||||||
"seconds": "{0} segons",
|
"seconds": "{0} segon | {0} segons",
|
||||||
"second_short": "{0}s",
|
"second_short": "{0}s",
|
||||||
"seconds_short": "{0}s",
|
"seconds_short": "{0}s",
|
||||||
"week": "{0} setmana",
|
"week": "{0} setmana",
|
||||||
"weeks": "{0} setmanes",
|
"weeks": "{0} setmana | {0} setmanes",
|
||||||
"week_short": "{0} setm.",
|
"week_short": "{0} setm.",
|
||||||
"weeks_short": "{0}setm.",
|
"weeks_short": "{0}setm.",
|
||||||
"year": "{0} any",
|
"year": "{0} any",
|
||||||
"years": "{0} anys",
|
"years": "{0} any | {0} anys",
|
||||||
"year_short": "{0} any",
|
"year_short": "{0} any",
|
||||||
"years_short": "{0}anys"
|
"years_short": "{0}anys"
|
||||||
}
|
}
|
||||||
|
@ -674,17 +674,17 @@
|
||||||
"collapse": "Replega",
|
"collapse": "Replega",
|
||||||
"conversation": "Conversa",
|
"conversation": "Conversa",
|
||||||
"error_fetching": "S'ha produït un error en carregar les entrades",
|
"error_fetching": "S'ha produït un error en carregar les entrades",
|
||||||
"load_older": "Carrega entrades anteriors",
|
"load_older": "Carrega apunts anteriors",
|
||||||
"no_retweet_hint": "L'entrada és només per a seguidores o és \"directa\", i per tant no es pot republicar",
|
"no_retweet_hint": "L'apunt és només per a seguidors o és \"directe\" i no es pot repetir o citar",
|
||||||
"repeated": "republicat",
|
"repeated": "repetit",
|
||||||
"show_new": "Mostra els nous",
|
"show_new": "Mostra els nous",
|
||||||
"up_to_date": "Actualitzat",
|
"up_to_date": "Actualitzat",
|
||||||
"socket_reconnected": "Connexió a temps real establerta",
|
"socket_reconnected": "Connexió a temps real establerta",
|
||||||
"socket_broke": "Connexió a temps real perduda: codi CloseEvent {0}",
|
"socket_broke": "Connexió a temps real perduda: codi CloseEvent {0}",
|
||||||
"error": "Error de càrrega de la línia de temps: {0}",
|
"error": "Error carregant la línia de temps: {0}",
|
||||||
"no_statuses": "No hi ha entrades",
|
"no_statuses": "No hi ha apunts",
|
||||||
"reload": "Recarrega",
|
"reload": "Recarrega",
|
||||||
"no_more_statuses": "No hi ha més entrades"
|
"no_more_statuses": "No hi ha més apunts"
|
||||||
},
|
},
|
||||||
"user_card": {
|
"user_card": {
|
||||||
"approve": "Aprova",
|
"approve": "Aprova",
|
||||||
|
@ -692,35 +692,35 @@
|
||||||
"blocked": "Bloquejat!",
|
"blocked": "Bloquejat!",
|
||||||
"deny": "Denega",
|
"deny": "Denega",
|
||||||
"follow": "Segueix",
|
"follow": "Segueix",
|
||||||
"followees": "Segueixo",
|
"followees": "Seguint",
|
||||||
"followers": "Seguidors/es",
|
"followers": "Seguidors",
|
||||||
"following": "Seguint!",
|
"following": "Seguint!",
|
||||||
"follows_you": "Et segueix!",
|
"follows_you": "Et segueix!",
|
||||||
"mute": "Silencia",
|
"mute": "Silencia",
|
||||||
"muted": "Silenciat",
|
"muted": "Silenciat",
|
||||||
"per_day": "per dia",
|
"per_day": "per dia",
|
||||||
"remote_follow": "Seguiment remot",
|
"remote_follow": "Seguiment remot",
|
||||||
"statuses": "Estats",
|
"statuses": "Apunts",
|
||||||
"unblock_progress": "Desbloquejant…",
|
"unblock_progress": "Desbloquejant…",
|
||||||
"unmute": "Deixa de silenciar",
|
"unmute": "Deixa de silenciar",
|
||||||
"follow_progress": "Sol·licitant…",
|
"follow_progress": "Sol·licitant…",
|
||||||
"admin_menu": {
|
"admin_menu": {
|
||||||
"force_nsfw": "Marca totes les entrades amb \"No segur per a entorns laborals\"",
|
"force_nsfw": "Marca tots els apunts amb \"No segur per a entorns laborals\"",
|
||||||
"strip_media": "Esborra els audiovisuals de les entrades",
|
"strip_media": "Esborra els Mèdia dels apunts",
|
||||||
"disable_any_subscription": "Deshabilita completament seguir algú",
|
"disable_any_subscription": "Deshabilita completament seguir algú",
|
||||||
"quarantine": "Deshabilita la federació a les entrades de les usuàries",
|
"quarantine": "Deshabilita la federació dels apunts dels usuaris",
|
||||||
"moderation": "Moderació",
|
"moderation": "Moderació",
|
||||||
"revoke_admin": "Revoca l'Admin",
|
"revoke_admin": "Revoca l'Admin",
|
||||||
"activate_account": "Activa el compte",
|
"activate_account": "Activa el compte",
|
||||||
"deactivate_account": "Desactiva el compte",
|
"deactivate_account": "Desactiva el compte",
|
||||||
"revoke_moderator": "Revoca Moderació",
|
"revoke_moderator": "Revoca Moderador",
|
||||||
"delete_account": "Esborra el compte",
|
"delete_account": "Esborra el compte",
|
||||||
"disable_remote_subscription": "Deshabilita seguir algú des d'una instància remota",
|
"disable_remote_subscription": "Deshabilita seguir algú des d'una instància remota",
|
||||||
"delete_user": "Esborra la usuària",
|
"delete_user": "Esborra l'usuari",
|
||||||
"grant_admin": "Concedir permisos d'Administració",
|
"grant_admin": "Concedir permisos d'Administrador",
|
||||||
"grant_moderator": "Concedir permisos de Moderació",
|
"grant_moderator": "Concedir permisos de Moderador",
|
||||||
"force_unlisted": "Força que les publicacions no estiguin llistades",
|
"force_unlisted": "Força que els apunts no estiguin llistats",
|
||||||
"sandbox": "Força que els missatges siguin només seguidors",
|
"sandbox": "Força que els apunts siguin només per a seguidors",
|
||||||
"delete_user_data_and_deactivate_confirmation": "Això esborrarà permanentment les dades d'aquest compte i el desactivarà. Estàs absolutament segur?"
|
"delete_user_data_and_deactivate_confirmation": "Això esborrarà permanentment les dades d'aquest compte i el desactivarà. Estàs absolutament segur?"
|
||||||
},
|
},
|
||||||
"edit_profile": "Edita el perfil",
|
"edit_profile": "Edita el perfil",
|
||||||
|
@ -747,15 +747,15 @@
|
||||||
"striped": "Fons a ratlles",
|
"striped": "Fons a ratlles",
|
||||||
"side": "Ratlla lateral"
|
"side": "Ratlla lateral"
|
||||||
},
|
},
|
||||||
"media": "Media",
|
"media": "Mèdia",
|
||||||
"domain_muted": "Desbloqueja el domini",
|
"domain_muted": "Desbloqueja el domini",
|
||||||
"deactivated": "Desactivat",
|
"deactivated": "Desactivat",
|
||||||
"follow_cancel": "Cancel·la la sol·licitut",
|
"follow_cancel": "Cancel·la la sol·licitud",
|
||||||
"mute_domain": "Bloqueja el domini",
|
"mute_domain": "Bloqueja el domini",
|
||||||
"note": "Nota privada"
|
"note": "Nota privada"
|
||||||
},
|
},
|
||||||
"user_profile": {
|
"user_profile": {
|
||||||
"timeline_title": "Flux personal",
|
"timeline_title": "Línia de temps del usuari",
|
||||||
"profile_loading_error": "Disculpes, hi ha hagut un error carregant aquest perfil.",
|
"profile_loading_error": "Disculpes, hi ha hagut un error carregant aquest perfil.",
|
||||||
"profile_does_not_exist": "Disculpes, aquest perfil no existeix."
|
"profile_does_not_exist": "Disculpes, aquest perfil no existeix."
|
||||||
},
|
},
|
||||||
|
@ -865,29 +865,29 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"delete": "Esborra l'entrada",
|
"delete": "Esborra l'apunt",
|
||||||
"delete_confirm": "Segur que vols esborrar aquesta entrada?",
|
"delete_confirm": "Segur que vols esborrar aquest apunt?",
|
||||||
"thread_muted_and_words": ", té les paraules:",
|
"thread_muted_and_words": ", té les paraules:",
|
||||||
"show_full_subject": "Mostra tot el tema",
|
"show_full_subject": "Mostra tot l'assumpte",
|
||||||
"show_content": "Mostra el contingut",
|
"show_content": "Mostra el contingut",
|
||||||
"repeats": "Repeticions",
|
"repeats": "Repeticions",
|
||||||
"bookmark": "Marcadors",
|
"bookmark": "Marcador",
|
||||||
"status_unavailable": "Entrada no disponible",
|
"status_unavailable": "Apunt no disponible",
|
||||||
"expand": "Expandeix",
|
"expand": "Expandeix",
|
||||||
"copy_link": "Copia l'enllaç a l'entrada",
|
"copy_link": "Copia l'enllaç al apunt",
|
||||||
"hide_full_subject": "Amaga tot el tema",
|
"hide_full_subject": "Amaga tot l'assumpte",
|
||||||
"favorites": "Favorits",
|
"favorites": "Favorits",
|
||||||
"replies_list": "Contestacions:",
|
"replies_list": "Respostes:",
|
||||||
"mute_conversation": "Silencia la conversa",
|
"mute_conversation": "Silencia la conversa",
|
||||||
"thread_muted": "Fil silenciat",
|
"thread_muted": "Fil silenciat",
|
||||||
"hide_content": "Amaga el contingut",
|
"hide_content": "Amaga el contingut",
|
||||||
"status_deleted": "S'ha esborrat aquesta entrada",
|
"status_deleted": "Aquest apunt ha estat esborrat",
|
||||||
"nsfw": "No segur per a entorns laborals",
|
"nsfw": "No segur per a entorns laborals",
|
||||||
"unbookmark": "Desmarca",
|
"unbookmark": "Desmarca",
|
||||||
"external_source": "Font externa",
|
"external_source": "Font externa",
|
||||||
"unpin": "Deixa de destacar al perfil",
|
"unpin": "Deixa de destacar al perfil",
|
||||||
"pinned": "Destacat",
|
"pinned": "Destacat",
|
||||||
"reply_to": "Contesta a",
|
"reply_to": "Respon a",
|
||||||
"pin": "Destaca al perfil",
|
"pin": "Destaca al perfil",
|
||||||
"unmute_conversation": "Deixa de silenciar la conversa",
|
"unmute_conversation": "Deixa de silenciar la conversa",
|
||||||
"mentions": "Mencions",
|
"mentions": "Mencions",
|
||||||
|
@ -919,21 +919,21 @@
|
||||||
},
|
},
|
||||||
"user_reporting": {
|
"user_reporting": {
|
||||||
"additional_comments": "Comentaris addicionals",
|
"additional_comments": "Comentaris addicionals",
|
||||||
"forward_description": "Aquest compte és d'un altre servidor. Vols enviar una còpia del report allà també?",
|
"forward_description": "Aquest compte és d'un altre servidor. Vols enviar-hi una còpia del informe?",
|
||||||
"forward_to": "Endavant a {0}",
|
"forward_to": "Endavant a {0}",
|
||||||
"generic_error": "Hi ha hagut un error mentre s'estava processant la teva sol·licitud.",
|
"generic_error": "Hi ha hagut un error mentre s'estava processant la teva sol·licitud.",
|
||||||
"title": "Reportant {0}",
|
"title": "Reportant {0}",
|
||||||
"add_comment_description": "Aquest report serà enviat a la moderació a la instància. Pots donar una explicació de per què estàs reportant aquest compte:",
|
"add_comment_description": "El informe serà enviat als moderadors de l'instància. Pots donar una explicació de per què estàs reportant aquest compte:",
|
||||||
"submit": "Envia"
|
"submit": "Envia"
|
||||||
},
|
},
|
||||||
"tool_tip": {
|
"tool_tip": {
|
||||||
"add_reaction": "Afegeix una Reacció",
|
"add_reaction": "Afegeix una Reacció",
|
||||||
"accept_follow_request": "Accepta la sol·licitud de seguir",
|
"accept_follow_request": "Accepta la sol·licitud de seguiment",
|
||||||
"repeat": "Repeteix",
|
"repeat": "Repeteix",
|
||||||
"reply": "Respon",
|
"reply": "Respon",
|
||||||
"favorite": "Favorit",
|
"favorite": "Favorit",
|
||||||
"user_settings": "Configuració d'usuària",
|
"user_settings": "Configuració d'usuari",
|
||||||
"reject_follow_request": "Rebutja la sol·licitud de seguir",
|
"reject_follow_request": "Rebutja la sol·licitud de seguiment",
|
||||||
"bookmark": "Marcador",
|
"bookmark": "Marcador",
|
||||||
"media_upload": "Pujar multimèdia",
|
"media_upload": "Pujar multimèdia",
|
||||||
"quote": "Cita"
|
"quote": "Cita"
|
||||||
|
@ -967,13 +967,13 @@
|
||||||
"password_reset": "Reinicia la contrasenya",
|
"password_reset": "Reinicia la contrasenya",
|
||||||
"forgot_password": "Has oblidat la contrasenya?",
|
"forgot_password": "Has oblidat la contrasenya?",
|
||||||
"too_many_requests": "Has arribat al límit d'intents. Prova de nou d'aquí una estona.",
|
"too_many_requests": "Has arribat al límit d'intents. Prova de nou d'aquí una estona.",
|
||||||
"password_reset_required_but_mailer_is_disabled": "Has de reiniciar la teva contrasenya però el reinici de la contrasenya està deshabilitat. Si us plau, contacta l'administració de la teva instància.",
|
"password_reset_required_but_mailer_is_disabled": "Has de reiniciar la teva contrasenya però el reinici de la contrasenya està desactivat. Si us plau, contacta l'administrador de la teva instància.",
|
||||||
"placeholder": "El teu correu electrònic o nom d'usuària",
|
"placeholder": "El teu correu electrònic o nom d'usuari",
|
||||||
"instruction": "Introdueix la teva adreça de correu electrònic o nom d'usuària. T'enviarem un enllaç per reiniciar la teva contrasenya.",
|
"instruction": "Introdueix la teva adreça de correu electrònic o nom d'usuari. T'enviarem un enllaç per a reiniciar la teva contrasenya.",
|
||||||
"return_home": "Torna a la pàgina principal",
|
"return_home": "Torna a la pàgina principal",
|
||||||
"password_reset_required": "Has de reiniciar la teva contrasenya per iniciar la sessió.",
|
"password_reset_required": "Has de reiniciar la teva contrasenya per a iniciar la sessió.",
|
||||||
"password_reset_disabled": "El reinici de la contrasenya està deshabilitat. Si us plau, contacta l'administració de la teva instància.",
|
"password_reset_disabled": "El reinici de la contrasenya està desactivat. Si us plau, contacta l'administrador de la teva instància.",
|
||||||
"check_email": "Comprova que has rebut al correu electrònic un enllaç per reiniciar la teva contrasenya."
|
"check_email": "Comprova que has rebut al correu electrònic un enllaç per a reiniciar la teva contrasenya."
|
||||||
},
|
},
|
||||||
"file_type": {
|
"file_type": {
|
||||||
"image": "Imatge",
|
"image": "Imatge",
|
||||||
|
|
110
src/i18n/en.json
110
src/i18n/en.json
|
@ -18,12 +18,12 @@
|
||||||
"not_applicable": "N/A",
|
"not_applicable": "N/A",
|
||||||
"accept": "Accept",
|
"accept": "Accept",
|
||||||
"accept_desc": "This instance only accepts messages from the following instances:",
|
"accept_desc": "This instance only accepts messages from the following instances:",
|
||||||
"reject": "Reject",
|
"reject": "Instance Blocks",
|
||||||
"reject_desc": "This instance will not accept messages from the following instances:",
|
"reject_desc": "This instance blocks posts to and from the following instances:",
|
||||||
"quarantine": "Quarantine",
|
"quarantine": "Quarantine",
|
||||||
"quarantine_desc": "This instance will send only public posts to the following instances:",
|
"quarantine_desc": "This instance will not send posts to the following instances:",
|
||||||
"ftl_removal": "Removal from \"Known Network\" Timeline",
|
"ftl_removal": "Removal from Federated Timeline",
|
||||||
"ftl_removal_desc": "This instance removes these instances from \"Known Network\" timeline:",
|
"ftl_removal_desc": "This instance removes these instances from the Federated Timeline:",
|
||||||
"media_removal": "Media Removal",
|
"media_removal": "Media Removal",
|
||||||
"media_removal_desc": "This instance removes media from posts on the following instances:",
|
"media_removal_desc": "This instance removes media from posts on the following instances:",
|
||||||
"media_nsfw": "Media force-set as sensitive",
|
"media_nsfw": "Media force-set as sensitive",
|
||||||
|
@ -106,7 +106,8 @@
|
||||||
"direct": "Direct",
|
"direct": "Direct",
|
||||||
"private": "Followers-only",
|
"private": "Followers-only",
|
||||||
"public": "Public",
|
"public": "Public",
|
||||||
"unlisted": "Unlisted"
|
"unlisted": "Unlisted",
|
||||||
|
"local": "Local-only post -- only your instance can see this status"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"image_cropper": {
|
"image_cropper": {
|
||||||
|
@ -125,7 +126,7 @@
|
||||||
"description": "Log in with OAuth",
|
"description": "Log in with OAuth",
|
||||||
"logout": "Log out",
|
"logout": "Log out",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"placeholder": "myusername",
|
"placeholder": "i.e. bobvibes420",
|
||||||
"register": "Register",
|
"register": "Register",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
"hint": "Log in to join the discussion",
|
"hint": "Log in to join the discussion",
|
||||||
|
@ -148,18 +149,18 @@
|
||||||
"about": "About",
|
"about": "About",
|
||||||
"administration": "Administration",
|
"administration": "Administration",
|
||||||
"back": "Back",
|
"back": "Back",
|
||||||
"friend_requests": "Follow requests",
|
"friend_requests": "Follow Requests",
|
||||||
"mentions": "Mentions",
|
"mentions": "Mentions",
|
||||||
"interactions": "Interactions",
|
"interactions": "Interactions",
|
||||||
"dms": "Direct messages",
|
"dms": "Direct Messages",
|
||||||
"public_tl": "Public timeline",
|
"public_tl": "Local Timeline",
|
||||||
"public_timeline_description": "Public posts from this instance",
|
"public_timeline_description": "Public posts from this instance",
|
||||||
"timeline": "Timeline",
|
"timeline": "Timeline",
|
||||||
"home_timeline": "Home timeline",
|
"home_timeline": "Home Timeline",
|
||||||
"home_timeline_description": "Posts from people you follow",
|
"home_timeline_description": "Posts from people you follow",
|
||||||
"bubble_timeline": "Bubble timeline",
|
"bubble_timeline": "Recommended Instances",
|
||||||
"bubble_timeline_description": "Posts from instances close to yours, as recommended by the admins",
|
"bubble_timeline_description": "Posts from instances close to yours, as recommended by the admins",
|
||||||
"twkn": "Known Network",
|
"twkn": "Federated Timeline",
|
||||||
"twkn_timeline_description": "Posts from the entire network",
|
"twkn_timeline_description": "Posts from the entire network",
|
||||||
"bookmarks": "Bookmarks",
|
"bookmarks": "Bookmarks",
|
||||||
"user_search": "User Search",
|
"user_search": "User Search",
|
||||||
|
@ -180,7 +181,7 @@
|
||||||
"load_older": "Load older notifications",
|
"load_older": "Load older notifications",
|
||||||
"notifications": "Notifications",
|
"notifications": "Notifications",
|
||||||
"read": "Read!",
|
"read": "Read!",
|
||||||
"repeated_you": "repeated your status",
|
"repeated_you": "boosted your status",
|
||||||
"no_more_notifications": "No more notifications",
|
"no_more_notifications": "No more notifications",
|
||||||
"migrated_to": "migrated to",
|
"migrated_to": "migrated to",
|
||||||
"reacted_with": "reacted with {0}",
|
"reacted_with": "reacted with {0}",
|
||||||
|
@ -217,7 +218,7 @@
|
||||||
"storage_unavailable": "Pleroma could not access browser storage. Your login or your local settings won't be saved and you might encounter unexpected issues. Try enabling cookies."
|
"storage_unavailable": "Pleroma could not access browser storage. Your login or your local settings won't be saved and you might encounter unexpected issues. Try enabling cookies."
|
||||||
},
|
},
|
||||||
"interactions": {
|
"interactions": {
|
||||||
"favs_repeats": "Repeats and favorites",
|
"favs_repeats": "Boosts and favorites",
|
||||||
"follows": "New follows",
|
"follows": "New follows",
|
||||||
"moves": "User migrates",
|
"moves": "User migrates",
|
||||||
"load_older": "Load older interactions"
|
"load_older": "Load older interactions"
|
||||||
|
@ -236,8 +237,8 @@
|
||||||
"text/bbcode": "BBCode",
|
"text/bbcode": "BBCode",
|
||||||
"text/x.misskeymarkdown": "MFM"
|
"text/x.misskeymarkdown": "MFM"
|
||||||
},
|
},
|
||||||
"content_warning": "Subject (optional)",
|
"content_warning": "Content Warning / Subject (optional)",
|
||||||
"default": "Just arrived at Luna Nova Academy",
|
"default": "Just landed on Neptune",
|
||||||
"direct_warning_to_all": "This post will be visible to all the mentioned users.",
|
"direct_warning_to_all": "This post will be visible to all the mentioned users.",
|
||||||
"direct_warning_to_first_only": "This post will only be visible to the mentioned users at the beginning of the message.",
|
"direct_warning_to_first_only": "This post will only be visible to the mentioned users at the beginning of the message.",
|
||||||
"posting": "Posting",
|
"posting": "Posting",
|
||||||
|
@ -245,6 +246,9 @@
|
||||||
"preview": "Preview",
|
"preview": "Preview",
|
||||||
"preview_empty": "Empty",
|
"preview_empty": "Empty",
|
||||||
"empty_status_error": "Can't post an empty status with no files",
|
"empty_status_error": "Can't post an empty status with no files",
|
||||||
|
"edit_status": "Edit Status",
|
||||||
|
"edit_remote_warning": "Other instances may not support edits!",
|
||||||
|
"edit_unsupported_warning": "Polls and mentions will not be changed by editing.",
|
||||||
"media_description_error": "Failed to update media, try again",
|
"media_description_error": "Failed to update media, try again",
|
||||||
"scope_notice": {
|
"scope_notice": {
|
||||||
"public": "This post will be visible to everyone",
|
"public": "This post will be visible to everyone",
|
||||||
|
@ -257,7 +261,7 @@
|
||||||
"private": "Followers-only - post to followers only",
|
"private": "Followers-only - post to followers only",
|
||||||
"public": "Public - post to public timelines",
|
"public": "Public - post to public timelines",
|
||||||
"unlisted": "Unlisted - do not post to public timelines",
|
"unlisted": "Unlisted - do not post to public timelines",
|
||||||
"local": "Local - do not federate this post"
|
"local": "Local - only your instance can see this status"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"registration": {
|
"registration": {
|
||||||
|
@ -369,7 +373,17 @@
|
||||||
"changed_password": "Password changed successfully!",
|
"changed_password": "Password changed successfully!",
|
||||||
"chatMessageRadius": "Chat message",
|
"chatMessageRadius": "Chat message",
|
||||||
"collapse_subject": "Collapse posts with subjects",
|
"collapse_subject": "Collapse posts with subjects",
|
||||||
|
"columns": "Columns",
|
||||||
"composing": "Composing",
|
"composing": "Composing",
|
||||||
|
"confirmation_dialogs": "Confirmation options",
|
||||||
|
"confirm_dialogs": "Require confirmation for:",
|
||||||
|
"confirm_dialogs_repeat": "Repeating a post",
|
||||||
|
"confirm_dialogs_unfollow": "Unfollowing someone",
|
||||||
|
"confirm_dialogs_block": "Blocking someone",
|
||||||
|
"confirm_dialogs_mute": "Muting someone",
|
||||||
|
"confirm_dialogs_delete": "Deleting a post",
|
||||||
|
"confirm_dialogs_approve_follow": "Accepting a follow request",
|
||||||
|
"confirm_dialogs_deny_follow": "Rejecting a follow request",
|
||||||
"confirm_new_password": "Confirm new password",
|
"confirm_new_password": "Confirm new password",
|
||||||
"current_avatar": "Your current avatar",
|
"current_avatar": "Your current avatar",
|
||||||
"current_mascot": "Your current mascot",
|
"current_mascot": "Your current mascot",
|
||||||
|
@ -424,6 +438,10 @@
|
||||||
"hide_shoutbox": "Hide instance shoutbox",
|
"hide_shoutbox": "Hide instance shoutbox",
|
||||||
"right_sidebar": "Reverse order of columns",
|
"right_sidebar": "Reverse order of columns",
|
||||||
"always_show_post_button": "Always show floating New Post button",
|
"always_show_post_button": "Always show floating New Post button",
|
||||||
|
"hide_site_favicon": "Hide instance favicon in top panel",
|
||||||
|
"hide_site_name": "Hide instance name in top panel",
|
||||||
|
"hide_threads_with_blocked_users": "Hide threads mentioning blocked users",
|
||||||
|
"hide_user_stats": "Hide user statistics (e.g. the number of followers)",
|
||||||
"hide_wallpaper": "Hide instance wallpaper",
|
"hide_wallpaper": "Hide instance wallpaper",
|
||||||
"preload_images": "Preload images",
|
"preload_images": "Preload images",
|
||||||
"use_one_click_nsfw": "Open NSFW attachments with just one click",
|
"use_one_click_nsfw": "Open NSFW attachments with just one click",
|
||||||
|
@ -479,7 +497,7 @@
|
||||||
"notification_visibility_follows": "Follows",
|
"notification_visibility_follows": "Follows",
|
||||||
"notification_visibility_likes": "Favorites",
|
"notification_visibility_likes": "Favorites",
|
||||||
"notification_visibility_mentions": "Mentions",
|
"notification_visibility_mentions": "Mentions",
|
||||||
"notification_visibility_repeats": "Repeats",
|
"notification_visibility_repeats": "Boosts",
|
||||||
"notification_visibility_moves": "User Migrates",
|
"notification_visibility_moves": "User Migrates",
|
||||||
"notification_visibility_emoji_reactions": "Reactions",
|
"notification_visibility_emoji_reactions": "Reactions",
|
||||||
"notification_visibility_polls": "Ends of polls you voted in",
|
"notification_visibility_polls": "Ends of polls you voted in",
|
||||||
|
@ -540,6 +558,7 @@
|
||||||
"conversation_display": "Conversation display style",
|
"conversation_display": "Conversation display style",
|
||||||
"conversation_display_tree": "Tree-style",
|
"conversation_display_tree": "Tree-style",
|
||||||
"disable_sticky_headers": "Don't stick column headers to top of the screen",
|
"disable_sticky_headers": "Don't stick column headers to top of the screen",
|
||||||
|
"show_nav_shortcuts": "Show extra navigation shortcuts in top panel",
|
||||||
"show_scrollbars": "Show side column's scrollbars",
|
"show_scrollbars": "Show side column's scrollbars",
|
||||||
"third_column_mode": "When there's enough space, show third column containing",
|
"third_column_mode": "When there's enough space, show third column containing",
|
||||||
"third_column_mode_none": "Don't show third column at all",
|
"third_column_mode_none": "Don't show third column at all",
|
||||||
|
@ -556,8 +575,10 @@
|
||||||
"sensitive_by_default": "Mark posts as sensitive by default",
|
"sensitive_by_default": "Mark posts as sensitive by default",
|
||||||
"sensitive_if_subject": "Automatically mark images as sensitive if a subject line is specified",
|
"sensitive_if_subject": "Automatically mark images as sensitive if a subject line is specified",
|
||||||
"render_mfm": "Render Misskey Markdown",
|
"render_mfm": "Render Misskey Markdown",
|
||||||
|
"render_mfm_on_hover": "Pause MFM animations until status hover",
|
||||||
"useStreamingApiWarning": "It's cool use it. If it breaks refresh I guess?",
|
"useStreamingApiWarning": "It's cool use it. If it breaks refresh I guess?",
|
||||||
"stop_gifs": "Pause animated images until you hover on them",
|
"stop_gifs": "Pause animated images until you hover on them (breaks MFM emojis)",
|
||||||
|
"show_wider_shortcuts": "Show wider gap between top panel shortcuts",
|
||||||
"streaming": "Automatically show new posts when scrolled to the top",
|
"streaming": "Automatically show new posts when scrolled to the top",
|
||||||
"user_mutes": "Users",
|
"user_mutes": "Users",
|
||||||
"useStreamingApi": "Receive posts and notifications real-time",
|
"useStreamingApi": "Receive posts and notifications real-time",
|
||||||
|
@ -567,6 +588,7 @@
|
||||||
"theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.",
|
"theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.",
|
||||||
"theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.",
|
"theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.",
|
||||||
"tooltipRadius": "Tooltips/alerts",
|
"tooltipRadius": "Tooltips/alerts",
|
||||||
|
"translation_language": "Automatic Translation Language",
|
||||||
"type_domains_to_mute": "Search domains to mute",
|
"type_domains_to_mute": "Search domains to mute",
|
||||||
"upload_a_photo": "Upload a photo",
|
"upload_a_photo": "Upload a photo",
|
||||||
"user_settings": "User Settings",
|
"user_settings": "User Settings",
|
||||||
|
@ -776,8 +798,8 @@
|
||||||
"conversation": "Conversation",
|
"conversation": "Conversation",
|
||||||
"error": "Error fetching timeline: {0}",
|
"error": "Error fetching timeline: {0}",
|
||||||
"load_older": "Load older statuses",
|
"load_older": "Load older statuses",
|
||||||
"no_retweet_hint": "Post is marked as followers-only or direct and cannot be repeated or quoted",
|
"no_retweet_hint": "Post is marked as followers-only or direct and cannot be boosted or quoted",
|
||||||
"repeated": "repeated",
|
"repeated": "boosted",
|
||||||
"show_new": "Show new",
|
"show_new": "Show new",
|
||||||
"reload": "Reload",
|
"reload": "Reload",
|
||||||
"up_to_date": "Up-to-date",
|
"up_to_date": "Up-to-date",
|
||||||
|
@ -788,15 +810,28 @@
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"favorites": "Favorites",
|
"favorites": "Favorites",
|
||||||
"repeats": "Repeats",
|
"repeats": "Boosts",
|
||||||
"delete": "Delete status",
|
"delete": "Delete status",
|
||||||
"pin": "Pin on profile",
|
"pin": "Pin on profile",
|
||||||
"unpin": "Unpin from profile",
|
"unpin": "Unpin from profile",
|
||||||
"pinned": "Pinned",
|
"pinned": "Pinned",
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"unbookmark": "Unbookmark",
|
"unbookmark": "Unbookmark",
|
||||||
|
"translate": "Translate",
|
||||||
|
"translated_from": "Translated from {language}",
|
||||||
"delete_confirm": "Do you really want to delete this status?",
|
"delete_confirm": "Do you really want to delete this status?",
|
||||||
"reply_to": "Reply to",
|
"reply_to": "Reply to",
|
||||||
|
"delete_confirm_title": "Confirm deletion",
|
||||||
|
"edit": "Edit",
|
||||||
|
"edited_at": " (Edited {time})",
|
||||||
|
"edit_history": "Edit History",
|
||||||
|
"edit_history_modal_title": "Edited {historyCount} time | Edited {historyCount} times",
|
||||||
|
"delete_confirm_accept_button": "Yes, delete it",
|
||||||
|
"delete_confirm_cancel_button": "No, keep it",
|
||||||
|
"repeat_confirm": "Do you really want to repeat this status?",
|
||||||
|
"repeat_confirm_title": "Confirm repeat",
|
||||||
|
"repeat_confirm_accept_button": "Yes, repeat it",
|
||||||
|
"repeat_confirm_cancel_button": "No, don't repeat",
|
||||||
"mentions": "Mentions",
|
"mentions": "Mentions",
|
||||||
"replies_list": "Replies:",
|
"replies_list": "Replies:",
|
||||||
"replies_list_with_others": "Replies (+{numReplies} other): | Replies (+{numReplies} others):",
|
"replies_list_with_others": "Replies (+{numReplies} other): | Replies (+{numReplies} others):",
|
||||||
|
@ -841,10 +876,23 @@
|
||||||
},
|
},
|
||||||
"user_card": {
|
"user_card": {
|
||||||
"approve": "Approve",
|
"approve": "Approve",
|
||||||
|
"approve_confirm_title": "Approve follow request",
|
||||||
|
"approve_confirm": "Are you sure you want to let this user follow you?",
|
||||||
|
"approve_confirm_accept_button": "Yes, accept",
|
||||||
|
"approve_confirm_cancel_button": "No, cancel",
|
||||||
"block": "Block",
|
"block": "Block",
|
||||||
|
"block_confirm": "Are you sure you want to block {user}?",
|
||||||
|
"block_confirm_title": "Block user",
|
||||||
|
"block_confirm_cancel_button": "No, don't block",
|
||||||
|
"block_confirm_accept_button": "Yes, block",
|
||||||
|
"block_progress": "Blocking…",
|
||||||
"blocked": "Blocked!",
|
"blocked": "Blocked!",
|
||||||
"deactivated": "Deactivated",
|
"deactivated": "Deactivated",
|
||||||
"deny": "Deny",
|
"deny": "Deny",
|
||||||
|
"deny_confirm_title": "Deny follow request",
|
||||||
|
"deny_confirm": "Are you sure you want to deny this user's follow request?",
|
||||||
|
"deny_confirm_accept_button": "Yes, deny",
|
||||||
|
"deny_confirm_cancel_button": "No, cancel",
|
||||||
"edit_profile": "Edit profile",
|
"edit_profile": "Edit profile",
|
||||||
"favorites": "Favorites",
|
"favorites": "Favorites",
|
||||||
"follow": "Follow",
|
"follow": "Follow",
|
||||||
|
@ -862,9 +910,15 @@
|
||||||
"mention": "Mention",
|
"mention": "Mention",
|
||||||
"message": "Message",
|
"message": "Message",
|
||||||
"mute": "Mute",
|
"mute": "Mute",
|
||||||
|
"mute_confirm": "Are you sure you want to mute {user}?",
|
||||||
|
"mute_confirm_title": "Mute user",
|
||||||
|
"mute_confirm_cancel_button": "No, don't mute",
|
||||||
|
"mute_confirm_accept_button": "Yes, mute",
|
||||||
"muted": "Muted",
|
"muted": "Muted",
|
||||||
"per_day": "per day",
|
"per_day": "per day",
|
||||||
"remote_follow": "Remote follow",
|
"remote_follow": "Remote follow",
|
||||||
|
"remove_follower": "Remove follower",
|
||||||
|
"replies": "With Replies",
|
||||||
"report": "Report",
|
"report": "Report",
|
||||||
"statuses": "Statuses",
|
"statuses": "Statuses",
|
||||||
"subscribe": "Subscribe",
|
"subscribe": "Subscribe",
|
||||||
|
@ -872,11 +926,15 @@
|
||||||
"unblock": "Unblock",
|
"unblock": "Unblock",
|
||||||
"unblock_progress": "Unblocking…",
|
"unblock_progress": "Unblocking…",
|
||||||
"block_progress": "Blocking…",
|
"block_progress": "Blocking…",
|
||||||
|
"unfollow_confirm": "Are you sure you want to unfollow {user}?",
|
||||||
|
"unfollow_confirm_title": "Unfollow user",
|
||||||
|
"unfollow_confirm_cancel_button": "No, don't unfollow",
|
||||||
|
"unfollow_confirm_accept_button": "Yes, unfollow",
|
||||||
"unmute": "Unmute",
|
"unmute": "Unmute",
|
||||||
"unmute_progress": "Unmuting…",
|
"unmute_progress": "Unmuting…",
|
||||||
"mute_progress": "Muting…",
|
"mute_progress": "Muting…",
|
||||||
"hide_repeats": "Hide repeats",
|
"hide_repeats": "Hide boosts",
|
||||||
"show_repeats": "Show repeats",
|
"show_repeats": "Show boosts",
|
||||||
"domain_muted": "Unblock domain",
|
"domain_muted": "Unblock domain",
|
||||||
"mute_domain": "Block domain",
|
"mute_domain": "Block domain",
|
||||||
"bot": "Bot",
|
"bot": "Bot",
|
||||||
|
@ -928,7 +986,7 @@
|
||||||
"tool_tip": {
|
"tool_tip": {
|
||||||
"media_upload": "Upload media",
|
"media_upload": "Upload media",
|
||||||
"quote": "Quote",
|
"quote": "Quote",
|
||||||
"repeat": "Repeat",
|
"repeat": "Boost",
|
||||||
"reply": "Reply",
|
"reply": "Reply",
|
||||||
"favorite": "Favorite",
|
"favorite": "Favorite",
|
||||||
"add_reaction": "Add Reaction",
|
"add_reaction": "Add Reaction",
|
||||||
|
|
|
@ -561,69 +561,39 @@
|
||||||
"mention_link_display_full": "名前とドメイン、例: {'@'}foo{'@'}example.org",
|
"mention_link_display_full": "名前とドメイン、例: {'@'}foo{'@'}example.org",
|
||||||
"fun": "お楽しみ",
|
"fun": "お楽しみ",
|
||||||
"virtual_scrolling": "タイムラインの描画を最適化する",
|
"virtual_scrolling": "タイムラインの描画を最適化する",
|
||||||
"type_domains_to_mute": "ミュートしたいドメインを検索",
|
"word_filter": "単語フィルタ"
|
||||||
"useStreamingApiWarning": "(実験中で、投稿を取りこぼすかもしれないので、おすすめしません)",
|
|
||||||
"useStreamingApi": "投稿と通知を、すぐに受け取る",
|
|
||||||
"user_mutes": "ユーザー",
|
|
||||||
"reset_background_confirm": "本当にバックグラウンドを初期化しますか?",
|
|
||||||
"reset_banner_confirm": "本当にバナーを初期化しますか?",
|
|
||||||
"reset_avatar_confirm": "本当にアバターを初期化しますか?",
|
|
||||||
"hide_wallpaper": "インスタンスのバックグラウンドを隠す",
|
|
||||||
"reset_profile_background": "プロフィールのバックグラウンドを初期化",
|
|
||||||
"reset_profile_banner": "プロフィールのバナーを初期化",
|
|
||||||
"reset_avatar": "アバターを初期化",
|
|
||||||
"notification_visibility_emoji_reactions": "リアクション",
|
|
||||||
"notification_visibility_moves": "ユーザーの引っ越し",
|
|
||||||
"new_email": "新しいメールアドレス",
|
|
||||||
"post_look_feel": "投稿の見た目",
|
|
||||||
"mention_links": "メンションリンク",
|
|
||||||
"profile_fields": {
|
|
||||||
"value": "内容",
|
|
||||||
"name": "ラベル",
|
|
||||||
"add_field": "枠を追加",
|
|
||||||
"label": "プロフィール補足情報"
|
|
||||||
},
|
},
|
||||||
"accent": "アクセント",
|
"status": {
|
||||||
"mutes_imported": "ミュートをインポートしました!少し時間がかかるかもしれません。",
|
"bookmark": "ブックマーク",
|
||||||
"emoji_reactions_on_timeline": "絵文字リアクションをタイムラインに表示",
|
"copy_link": "リンクをコピー",
|
||||||
"domain_mutes": "ドメイン",
|
"delete": "ステータスを削除",
|
||||||
"mutes_and_blocks": "ミュートとブロック",
|
"delete_confirm": "本当にこのステータスを削除してもよろしいですか?",
|
||||||
"chatMessageRadius": "チャットメッセージ",
|
"expand": "広げる",
|
||||||
"change_email_error": "メールアドレスを変えることが、できなかったかもしれません。",
|
"external_source": "外部ソース",
|
||||||
"changed_email": "メールアドレスが、変わりました!",
|
"favorites": "お気に入り",
|
||||||
"change_email": "メールアドレスを変える",
|
"hide_content": "隠す",
|
||||||
"bot": "これは bot アカウントです",
|
"hide_full_subject": "隠す",
|
||||||
"mute_export_button": "ミュートをCSVファイルにエクスポートする",
|
"mentions": "メンション",
|
||||||
"import_mutes_from_a_csv_file": "CSVファイルからミュートをインポートする",
|
"mute_conversation": "スレッドをミュート",
|
||||||
"mute_import_error": "ミュートのインポートに失敗しました",
|
"nsfw": "閲覧注意",
|
||||||
"mute_import": "ミュートのインポート",
|
"pin": "プロフィールにピン留め",
|
||||||
"mute_export": "ミュートのエクスポート",
|
"pinned": "ピン留め",
|
||||||
"allow_following_move": "フォロー中のアカウントが引っ越したとき、自動フォローを許可する",
|
"plus_more": "ほか{number}件",
|
||||||
"setting_changed": "規定の設定と異なっています",
|
"repeats": "リピート",
|
||||||
"greentext": "引用を緑色で表示",
|
"replies_list": "返信:",
|
||||||
"sensitive_by_default": "はじめから投稿をセンシティブとして設定",
|
"reply_to": "返信",
|
||||||
"sensitive_if_subject": "ステータスにサブジェクトをついたらNSFWにする",
|
"show_content": "見る",
|
||||||
"render_mfm": "Misskey Markdownを表示",
|
"show_full_subject": "全部見る",
|
||||||
"more_settings": "その他の設定",
|
"status_deleted": "この投稿は削除されました",
|
||||||
"reply_visibility_self_short": "自分宛のリプライを見る",
|
"status_unavailable": "利用できません",
|
||||||
"reply_visibility_following_short": "フォローしている人に宛てられたリプライを見る",
|
"thread_muted": "ミュートされたスレッド",
|
||||||
"hide_all_muted_posts": "ミュートした投稿を隠す",
|
"thread_muted_and_words": "以下の単語を含むため:",
|
||||||
"hide_media_previews": "メディアのプレビューを隠す",
|
"translate": "翻訳",
|
||||||
"word_filter": "単語フィルタ",
|
"translated_from": "{language}から翻訳されました",
|
||||||
"file_export_import": {
|
"unbookmark": "ブックマーク解除",
|
||||||
"errors": {
|
"unmute_conversation": "スレッドのミュートを解除",
|
||||||
"invalid_file": "これはPleromaの設定をバックアップしたファイルではありません。",
|
"unpin": "プロフィールのピン留めを外す",
|
||||||
"file_slightly_new": "ファイルのマイナーバージョンが異なり、一部の設定が読み込まれないことがあります"
|
"you": "(あなた)"
|
||||||
},
|
|
||||||
"restore_settings": "設定をファイルから復元する",
|
|
||||||
"backup_settings_theme": "テーマを含む設定をファイルにバックアップする",
|
|
||||||
"backup_settings": "設定をファイルにバックアップする",
|
|
||||||
"backup_restore": "設定をバックアップ"
|
|
||||||
},
|
|
||||||
"save": "変更を保存",
|
|
||||||
"hide_shoutbox": "Shoutboxを表示しない",
|
|
||||||
"always_show_post_button": "投稿ボタンを常に表示",
|
|
||||||
"right_sidebar": "サイドバーを右に表示"
|
|
||||||
},
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"now": "たった今",
|
"now": "たった今",
|
||||||
|
|
|
@ -19,6 +19,8 @@ import reportsModule from './modules/reports.js'
|
||||||
import pollsModule from './modules/polls.js'
|
import pollsModule from './modules/polls.js'
|
||||||
import postStatusModule from './modules/postStatus.js'
|
import postStatusModule from './modules/postStatus.js'
|
||||||
import announcementsModule from './modules/announcements.js'
|
import announcementsModule from './modules/announcements.js'
|
||||||
|
import editStatusModule from './modules/editStatus.js'
|
||||||
|
import statusHistoryModule from './modules/statusHistory.js'
|
||||||
|
|
||||||
import { createI18n } from 'vue-i18n'
|
import { createI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
@ -81,7 +83,9 @@ const persistedStateOptions = {
|
||||||
reports: reportsModule,
|
reports: reportsModule,
|
||||||
polls: pollsModule,
|
polls: pollsModule,
|
||||||
postStatus: postStatusModule,
|
postStatus: postStatusModule,
|
||||||
announcements: announcementsModule
|
announcements: announcementsModule,
|
||||||
|
editStatus: editStatusModule,
|
||||||
|
statusHistory: statusHistoryModule
|
||||||
},
|
},
|
||||||
plugins,
|
plugins,
|
||||||
strict: false // Socket modifies itself, let's ignore this for now.
|
strict: false // Socket modifies itself, let's ignore this for now.
|
||||||
|
|
|
@ -98,6 +98,13 @@ const api = {
|
||||||
showImmediately: timelineData.visibleStatuses.length === 0,
|
showImmediately: timelineData.visibleStatuses.length === 0,
|
||||||
timeline: 'friends'
|
timeline: 'friends'
|
||||||
})
|
})
|
||||||
|
} else if (message.event === 'status.update') {
|
||||||
|
dispatch('addNewStatuses', {
|
||||||
|
statuses: [message.status],
|
||||||
|
userId: false,
|
||||||
|
showImmediately: message.status.id in timelineData.visibleStatusesObject,
|
||||||
|
timeline: 'friends'
|
||||||
|
})
|
||||||
} else if (message.event === 'delete') {
|
} else if (message.event === 'delete') {
|
||||||
dispatch('deleteStatusById', message.id)
|
dispatch('deleteStatusById', message.id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,15 @@ export const defaultState = {
|
||||||
// bad name: actually hides posts of muted USERS
|
// bad name: actually hides posts of muted USERS
|
||||||
hideMutedPosts: undefined, // instance default
|
hideMutedPosts: undefined, // instance default
|
||||||
hideMutedThreads: undefined, // instance default
|
hideMutedThreads: undefined, // instance default
|
||||||
|
hideThreadsWithBlockedUsers: undefined, // instance default
|
||||||
hideWordFilteredPosts: undefined, // instance default
|
hideWordFilteredPosts: undefined, // instance default
|
||||||
muteBotStatuses: undefined, // instance default
|
muteBotStatuses: undefined, // instance default
|
||||||
collapseMessageWithSubject: undefined, // instance default
|
collapseMessageWithSubject: true, // instance default
|
||||||
padEmoji: true,
|
padEmoji: true,
|
||||||
|
showNavShortcuts: undefined, // instance default
|
||||||
|
showWiderShortcuts: undefined, // instance default
|
||||||
|
hideSiteFavicon: undefined, // instance default
|
||||||
|
hideSiteName: undefined, // instance default
|
||||||
hideAttachments: false,
|
hideAttachments: false,
|
||||||
hideAttachmentsInConv: false,
|
hideAttachmentsInConv: false,
|
||||||
maxThumbnails: 16,
|
maxThumbnails: 16,
|
||||||
|
@ -44,11 +49,11 @@ export const defaultState = {
|
||||||
loopVideoSilentOnly: true,
|
loopVideoSilentOnly: true,
|
||||||
streaming: false,
|
streaming: false,
|
||||||
emojiReactionsOnTimeline: true,
|
emojiReactionsOnTimeline: true,
|
||||||
alwaysShowNewPostButton: false,
|
alwaysShowNewPostButton: true,
|
||||||
autohideFloatingPostButton: false,
|
autohideFloatingPostButton: false,
|
||||||
pauseOnUnfocused: true,
|
pauseOnUnfocused: true,
|
||||||
stopGifs: true,
|
stopGifs: false,
|
||||||
replyVisibility: 'all',
|
replyVisibility: 'following',
|
||||||
thirdColumnMode: 'notifications',
|
thirdColumnMode: 'notifications',
|
||||||
notificationVisibility: {
|
notificationVisibility: {
|
||||||
follows: true,
|
follows: true,
|
||||||
|
@ -66,7 +71,7 @@ export const defaultState = {
|
||||||
highlight: {},
|
highlight: {},
|
||||||
interfaceLanguage: browserLocale,
|
interfaceLanguage: browserLocale,
|
||||||
hideScopeNotice: false,
|
hideScopeNotice: false,
|
||||||
useStreamingApi: true,
|
useStreamingApi: false,
|
||||||
sidebarRight: undefined, // instance default
|
sidebarRight: undefined, // instance default
|
||||||
scopeCopy: undefined, // instance default
|
scopeCopy: undefined, // instance default
|
||||||
subjectLineBehavior: undefined, // instance default
|
subjectLineBehavior: undefined, // instance default
|
||||||
|
@ -75,6 +80,14 @@ export const defaultState = {
|
||||||
minimalScopesMode: undefined, // instance default
|
minimalScopesMode: undefined, // instance default
|
||||||
// This hides statuses filtered via a word filter
|
// This hides statuses filtered via a word filter
|
||||||
hideFilteredStatuses: undefined, // instance default
|
hideFilteredStatuses: undefined, // instance default
|
||||||
|
modalOnRepeat: undefined, // instance default
|
||||||
|
modalOnUnfollow: undefined, // instance default
|
||||||
|
modalOnBlock: undefined, // instance default
|
||||||
|
modalOnMute: undefined, // instance default
|
||||||
|
modalOnDelete: undefined, // instance default
|
||||||
|
modalOnLogout: undefined, // instance default
|
||||||
|
modalOnApproveFollow: undefined, // instance default
|
||||||
|
modalOnDenyFollow: undefined, // instance default
|
||||||
playVideosInModal: false,
|
playVideosInModal: false,
|
||||||
useOneClickNsfw: false,
|
useOneClickNsfw: false,
|
||||||
useContainFit: true,
|
useContainFit: true,
|
||||||
|
@ -84,7 +97,7 @@ export const defaultState = {
|
||||||
useAtIcon: undefined, // instance default
|
useAtIcon: undefined, // instance default
|
||||||
mentionLinkDisplay: undefined, // instance default
|
mentionLinkDisplay: undefined, // instance default
|
||||||
mentionLinkShowTooltip: undefined, // instance default
|
mentionLinkShowTooltip: undefined, // instance default
|
||||||
mentionLinkShowAvatar: undefined, // instance default
|
mentionLinkShowAvatar: true, // instance default
|
||||||
mentionLinkFadeDomain: undefined, // instance default
|
mentionLinkFadeDomain: undefined, // instance default
|
||||||
mentionLinkShowYous: undefined, // instance default
|
mentionLinkShowYous: undefined, // instance default
|
||||||
mentionLinkBoldenYou: undefined, // instance default
|
mentionLinkBoldenYou: undefined, // instance default
|
||||||
|
@ -94,12 +107,14 @@ export const defaultState = {
|
||||||
virtualScrolling: undefined, // instance default
|
virtualScrolling: undefined, // instance default
|
||||||
sensitiveByDefault: undefined, // instance default
|
sensitiveByDefault: undefined, // instance default
|
||||||
sensitiveIfSubject: undefined,
|
sensitiveIfSubject: undefined,
|
||||||
renderMisskeyMarkdown: undefined,
|
renderMisskeyMarkdown: true,
|
||||||
|
mfmOnHover: undefined, // instance default
|
||||||
conversationDisplay: undefined, // instance default
|
conversationDisplay: undefined, // instance default
|
||||||
conversationTreeAdvanced: undefined, // instance default
|
conversationTreeAdvanced: undefined, // instance default
|
||||||
conversationOtherRepliesButton: undefined, // instance default
|
conversationOtherRepliesButton: undefined, // instance default
|
||||||
conversationTreeFadeAncestors: undefined, // instance default
|
conversationTreeFadeAncestors: undefined, // instance default
|
||||||
maxDepthInThread: undefined // instance default
|
maxDepthInThread: undefined, // instance default
|
||||||
|
translationLanguage: undefined // instance default
|
||||||
}
|
}
|
||||||
|
|
||||||
// caching the instance default properties
|
// caching the instance default properties
|
||||||
|
@ -172,6 +187,7 @@ const config = {
|
||||||
case 'interfaceLanguage':
|
case 'interfaceLanguage':
|
||||||
messages.setLanguage(this.getters.i18n, value)
|
messages.setLanguage(this.getters.i18n, value)
|
||||||
Cookies.set(BACKEND_LANGUAGE_COOKIE_NAME, localeService.internalToBackendLocale(value))
|
Cookies.set(BACKEND_LANGUAGE_COOKIE_NAME, localeService.internalToBackendLocale(value))
|
||||||
|
dispatch('setInstanceOption', { name: 'interfaceLanguage', value })
|
||||||
break
|
break
|
||||||
case 'thirdColumnMode':
|
case 'thirdColumnMode':
|
||||||
dispatch('setLayoutWidth', undefined)
|
dispatch('setLayoutWidth', undefined)
|
||||||
|
|
25
src/modules/editStatus.js
Normal file
25
src/modules/editStatus.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
const editStatus = {
|
||||||
|
state: {
|
||||||
|
params: null,
|
||||||
|
modalActivated: false
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
openEditStatusModal (state, params) {
|
||||||
|
state.params = params
|
||||||
|
state.modalActivated = true
|
||||||
|
},
|
||||||
|
closeEditStatusModal (state) {
|
||||||
|
state.modalActivated = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
openEditStatusModal ({ commit }, params) {
|
||||||
|
commit('openEditStatusModal', params)
|
||||||
|
},
|
||||||
|
closeEditStatusModal ({ commit }) {
|
||||||
|
commit('closeEditStatusModal')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default editStatus
|
|
@ -17,8 +17,8 @@ const defaultState = {
|
||||||
defaultAvatar: '/images/avi.png',
|
defaultAvatar: '/images/avi.png',
|
||||||
defaultBanner: '/images/banner.png',
|
defaultBanner: '/images/banner.png',
|
||||||
background: '/static/aurora_borealis.jpg',
|
background: '/static/aurora_borealis.jpg',
|
||||||
collapseMessageWithSubject: false,
|
collapseMessageWithSubject: true,
|
||||||
greentext: false,
|
greentext: true,
|
||||||
useAtIcon: false,
|
useAtIcon: false,
|
||||||
mentionLinkDisplay: 'short',
|
mentionLinkDisplay: 'short',
|
||||||
mentionLinkShowTooltip: true,
|
mentionLinkShowTooltip: true,
|
||||||
|
@ -30,12 +30,22 @@ const defaultState = {
|
||||||
// bad name: actually hides posts of muted USERS
|
// bad name: actually hides posts of muted USERS
|
||||||
hideMutedPosts: false,
|
hideMutedPosts: false,
|
||||||
hideMutedThreads: true,
|
hideMutedThreads: true,
|
||||||
|
hideThreadsWithBlockedUsers: false,
|
||||||
hideWordFilteredPosts: false,
|
hideWordFilteredPosts: false,
|
||||||
hidePostStats: false,
|
hidePostStats: false,
|
||||||
hideBotIndication: false,
|
hideBotIndication: false,
|
||||||
hideSitename: false,
|
hideSiteFavicon: false,
|
||||||
|
hideSiteName: false,
|
||||||
hideUserStats: false,
|
hideUserStats: false,
|
||||||
muteBotStatuses: false,
|
muteBotStatuses: false,
|
||||||
|
modalOnRepeat: false,
|
||||||
|
modalOnUnfollow: false,
|
||||||
|
modalOnBlock: true,
|
||||||
|
modalOnMute: false,
|
||||||
|
modalOnDelete: true,
|
||||||
|
modalOnLogout: true,
|
||||||
|
modalOnApproveFollow: false,
|
||||||
|
modalOnDenyFollow: false,
|
||||||
loginMethod: 'password',
|
loginMethod: 'password',
|
||||||
logo: '/static/logo.svg',
|
logo: '/static/logo.svg',
|
||||||
logoMargin: '.2em',
|
logoMargin: '.2em',
|
||||||
|
@ -49,13 +59,16 @@ const defaultState = {
|
||||||
scopeCopy: true,
|
scopeCopy: true,
|
||||||
showFeaturesPanel: true,
|
showFeaturesPanel: true,
|
||||||
showInstanceSpecificPanel: false,
|
showInstanceSpecificPanel: false,
|
||||||
|
showNavShortcuts: true,
|
||||||
|
showWiderShortcuts: false,
|
||||||
sidebarRight: false,
|
sidebarRight: false,
|
||||||
subjectLineBehavior: 'email',
|
subjectLineBehavior: 'email',
|
||||||
theme: 'pleroma-dark',
|
theme: 'pleroma-dark',
|
||||||
virtualScrolling: true,
|
virtualScrolling: true,
|
||||||
sensitiveByDefault: false,
|
sensitiveByDefault: false,
|
||||||
sensitiveIfSubject: true,
|
sensitiveIfSubject: true,
|
||||||
renderMisskeyMarkdown: false,
|
renderMisskeyMarkdown: true,
|
||||||
|
mfmOnHover: false,
|
||||||
conversationDisplay: 'linear',
|
conversationDisplay: 'linear',
|
||||||
conversationTreeAdvanced: false,
|
conversationTreeAdvanced: false,
|
||||||
conversationOtherRepliesButton: 'below',
|
conversationOtherRepliesButton: 'below',
|
||||||
|
@ -153,7 +166,7 @@ const instance = {
|
||||||
|
|
||||||
async getCustomEmoji ({ commit, state }) {
|
async getCustomEmoji ({ commit, state }) {
|
||||||
try {
|
try {
|
||||||
const res = await window.fetch('/api/pleroma/emoji.json')
|
const res = await window.fetch('/api/v1/pleroma/emoji')
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const result = await res.json()
|
const result = await res.json()
|
||||||
const values = Array.isArray(result) ? Object.assign({}, ...result) : result
|
const values = Array.isArray(result) ? Object.assign({}, ...result) : result
|
||||||
|
|
25
src/modules/statusHistory.js
Normal file
25
src/modules/statusHistory.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
const statusHistory = {
|
||||||
|
state: {
|
||||||
|
params: {},
|
||||||
|
modalActivated: false
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
openStatusHistoryModal (state, params) {
|
||||||
|
state.params = params
|
||||||
|
state.modalActivated = true
|
||||||
|
},
|
||||||
|
closeStatusHistoryModal (state) {
|
||||||
|
state.modalActivated = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
openStatusHistoryModal ({ commit }, params) {
|
||||||
|
commit('openStatusHistoryModal', params)
|
||||||
|
},
|
||||||
|
closeStatusHistoryModal ({ commit }) {
|
||||||
|
commit('closeStatusHistoryModal')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default statusHistory
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue