forked from AkkomaGang/akkoma-fe
Compare commits
76 commits
disqordia
...
profile-re
Author | SHA1 | Date | |
---|---|---|---|
0dbe31cf31 | |||
|
be20668f1f | ||
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 |
83 changed files with 1772 additions and 489 deletions
|
@ -6,7 +6,11 @@ This is a fork of Pleroma-FE from the Pleroma project, with support for new Akko
|
|||
|
||||
# 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
|
||||
|
||||
|
|
10
index.html
10
index.html
|
@ -10,11 +10,21 @@
|
|||
<link rel="stylesheet" href="/static/font/css/lato.css">
|
||||
<link rel="stylesheet" href="/static/mfm.css">
|
||||
<!--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">
|
||||
</head>
|
||||
<body class="hidden">
|
||||
<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="modal"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
<UserReportingModal />
|
||||
<PostStatusModal />
|
||||
<SettingsModal />
|
||||
<div id="modal" />
|
||||
<UpdateNotification />
|
||||
<GlobalNoticeList />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -250,6 +250,7 @@ const getNodeInfo = async ({ store }) => {
|
|||
store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
|
||||
store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
|
||||
store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled })
|
||||
store.dispatch('setInstanceOption', { name: 'translationEnabled', value: features.includes('akkoma:machine_translation') })
|
||||
|
||||
const uploadLimits = metadata.uploadLimits
|
||||
store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })
|
||||
|
|
|
@ -13,6 +13,8 @@ const About = {
|
|||
MRFTransparencyPanel
|
||||
},
|
||||
computed: {
|
||||
currentUser () { return this.$store.state.users.currentUser },
|
||||
privateMode () { return this.$store.state.instance.private },
|
||||
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
|
||||
showInstanceSpecificPanel () {
|
||||
return this.$store.state.instance.showInstanceSpecificPanel &&
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="column-inner">
|
||||
<instance-specific-panel v-if="showInstanceSpecificPanel" />
|
||||
<staff-panel />
|
||||
<!--<instance-specific-panel v-if="showInstanceSpecificPanel" />-->
|
||||
<staff-panel v-if="currentUser || !privateMode" />
|
||||
<terms-of-service-panel />
|
||||
<MRFTransparencyPanel />
|
||||
<features-panel v-if="showFeaturesPanel" />
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import ProgressButton from '../progress_button/progress_button.vue'
|
||||
import Popover from '../popover/popover.vue'
|
||||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { mapState } from 'vuex'
|
||||
import {
|
||||
faEllipsisV
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
@ -14,13 +16,22 @@ const AccountActions = {
|
|||
'user', 'relationship'
|
||||
],
|
||||
data () {
|
||||
return { }
|
||||
return {
|
||||
showingConfirmBlock: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ProgressButton,
|
||||
Popover
|
||||
Popover,
|
||||
ConfirmModal
|
||||
},
|
||||
methods: {
|
||||
showConfirmBlock () {
|
||||
this.showingConfirmBlock = true
|
||||
},
|
||||
hideConfirmBlock () {
|
||||
this.showingConfirmBlock = false
|
||||
},
|
||||
showRepeats () {
|
||||
this.$store.dispatch('showReblogs', this.user.id)
|
||||
},
|
||||
|
@ -28,7 +39,15 @@ const AccountActions = {
|
|||
this.$store.dispatch('hideReblogs', this.user.id)
|
||||
},
|
||||
blockUser () {
|
||||
if (!this.shouldConfirmBlock) {
|
||||
this.doBlockUser()
|
||||
} else {
|
||||
this.showConfirmBlock()
|
||||
}
|
||||
},
|
||||
doBlockUser () {
|
||||
this.$store.dispatch('blockUser', this.user.id)
|
||||
this.hideConfirmBlock()
|
||||
},
|
||||
unblockUser () {
|
||||
this.$store.dispatch('unblockUser', this.user.id)
|
||||
|
@ -36,6 +55,14 @@ const AccountActions = {
|
|||
reportUser () {
|
||||
this.$store.dispatch('openUserReportingModal', { userId: this.user.id })
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
shouldConfirmBlock () {
|
||||
return this.$store.getters.mergedConfig.modalOnBlock
|
||||
},
|
||||
...mapState({
|
||||
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,27 @@
|
|||
</button>
|
||||
</template>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
|
|
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: {
|
||||
statusId () {
|
||||
return this.$route.params.id
|
||||
}
|
||||
},
|
||||
currentUser () {
|
||||
return this.$store.state.users.currentUser
|
||||
},
|
||||
privateMode () { return this.$store.state.instance.private }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,22 @@
|
|||
<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
|
||||
v-else
|
||||
:collapsable="false"
|
||||
is-page="true"
|
||||
:status-id="statusId"
|
||||
|
@ -7,3 +24,23 @@
|
|||
</template>
|
||||
|
||||
<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,4 +1,5 @@
|
|||
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 {
|
||||
faSignInAlt,
|
||||
|
@ -11,6 +12,11 @@ import {
|
|||
faSearch,
|
||||
faTachometerAlt,
|
||||
faCog,
|
||||
faGlobe,
|
||||
faBolt,
|
||||
faUsers,
|
||||
faCommentMedical,
|
||||
faBookmark,
|
||||
faInfoCircle
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
|
@ -25,12 +31,18 @@ library.add(
|
|||
faSearch,
|
||||
faTachometerAlt,
|
||||
faCog,
|
||||
faGlobe,
|
||||
faBolt,
|
||||
faUsers,
|
||||
faCommentMedical,
|
||||
faBookmark,
|
||||
faInfoCircle
|
||||
)
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SearchBar
|
||||
SearchBar,
|
||||
ConfirmModal
|
||||
},
|
||||
data: () => ({
|
||||
searchBarHidden: true,
|
||||
|
@ -40,7 +52,8 @@ export default {
|
|||
window.CSS.supports('-moz-mask-size', 'contain') ||
|
||||
window.CSS.supports('-ms-mask-size', 'contain') ||
|
||||
window.CSS.supports('-o-mask-size', 'contain')
|
||||
)
|
||||
),
|
||||
showingConfirmLogout: false
|
||||
}),
|
||||
computed: {
|
||||
enableMask () { return this.supportsMask && this.$store.state.instance.logoMask },
|
||||
|
@ -65,20 +78,34 @@ export default {
|
|||
})
|
||||
},
|
||||
logo () { return this.$store.state.instance.logo },
|
||||
mergedConfig () {
|
||||
return this.$store.getters.mergedConfig
|
||||
},
|
||||
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 },
|
||||
logoLeft () { return this.$store.state.instance.logoLeft },
|
||||
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: {
|
||||
scrollToTop () {
|
||||
window.scrollTo(0, 0)
|
||||
},
|
||||
logout () {
|
||||
this.$router.replace('/main/public')
|
||||
this.$store.dispatch('logout')
|
||||
},
|
||||
onSearchBarToggled (hidden) {
|
||||
this.searchBarHidden = hidden
|
||||
},
|
||||
|
|
|
@ -15,16 +15,16 @@
|
|||
display: grid;
|
||||
grid-template-rows: var(--navbar-height);
|
||||
grid-template-columns: 2fr auto 2fr;
|
||||
grid-template-areas: "sitename logo actions";
|
||||
grid-template-areas: "nav-left logo actions";
|
||||
box-sizing: border-box;
|
||||
padding: 0 1.2em;
|
||||
margin: auto;
|
||||
max-width: 980px;
|
||||
max-width: 1110px;
|
||||
}
|
||||
|
||||
&.-logoLeft .inner-nav {
|
||||
grid-template-columns: auto 2fr 2fr;
|
||||
grid-template-areas: "logo sitename actions";
|
||||
grid-template-areas: "logo nav-left actions";
|
||||
}
|
||||
|
||||
.button-default {
|
||||
|
@ -84,24 +84,52 @@
|
|||
}
|
||||
|
||||
.nav-icon {
|
||||
margin-left: 1em;
|
||||
margin-left: 0.2em;
|
||||
width: 2em;
|
||||
height: 100%;
|
||||
font-size: 130%;
|
||||
text-align: center;
|
||||
|
||||
&-logout {
|
||||
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 {
|
||||
color: $fallback--link;
|
||||
color: var(--topBarLink, $fallback--link);
|
||||
}
|
||||
}
|
||||
|
||||
.sitename {
|
||||
grid-area: sitename;
|
||||
.-wide {
|
||||
.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 {
|
||||
|
@ -120,5 +148,10 @@
|
|||
justify-content: flex-end;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&.left {
|
||||
justify-content: flex-start;
|
||||
text-alignt: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,16 +5,79 @@
|
|||
:class="{ '-logoLeft': logoLeft }"
|
||||
@click="scrollToTop()"
|
||||
>
|
||||
<div class="inner-nav">
|
||||
<div class="item sitename">
|
||||
<div
|
||||
class="inner-nav"
|
||||
:class="{ '-wide': showWiderShortcuts }"
|
||||
>
|
||||
<div class="item nav-left-wrapper">
|
||||
<router-link
|
||||
v-if="!hideSitename"
|
||||
class="site-name"
|
||||
class="site-brand"
|
||||
:to="{ name: 'root' }"
|
||||
active-class="home"
|
||||
>
|
||||
{{ sitename }}
|
||||
<img
|
||||
v-if="!hideSiteFavicon"
|
||||
class="favicon"
|
||||
src="/favicon.png"
|
||||
>
|
||||
<span
|
||||
v-if="!hideSiteName"
|
||||
class="site-name"
|
||||
>
|
||||
{{ sitename }}
|
||||
</span>
|
||||
</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>
|
||||
<router-link
|
||||
class="logo"
|
||||
|
@ -36,6 +99,46 @@
|
|||
@toggled="onSearchBarToggled"
|
||||
@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
|
||||
class="button-unstyled nav-icon"
|
||||
@click.stop="openSettingsModal"
|
||||
|
@ -61,20 +164,20 @@
|
|||
:title="$t('nav.administration')"
|
||||
/>
|
||||
</a>
|
||||
<button
|
||||
v-if="currentUser"
|
||||
class="button-unstyled nav-icon nav-icon-logout"
|
||||
@click.prevent="logout"
|
||||
>
|
||||
<FAIcon
|
||||
fixed-width
|
||||
class="fa-scale-110 fa-old-padding"
|
||||
icon="sign-out-alt"
|
||||
:title="$t('login.logout')"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
</nav>
|
||||
</template>
|
||||
<script src="./desktop_nav.js"></script>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
right: 0;
|
||||
top: 0;
|
||||
background: rgba(27,31,35,.5);
|
||||
z-index: 99;
|
||||
z-index: 2000;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
|||
margin: 15vh auto;
|
||||
position: fixed;
|
||||
transform: translateX(-50%);
|
||||
z-index: 999;
|
||||
z-index: 2001;
|
||||
cursor: default;
|
||||
display: block;
|
||||
background-color: $fallback--bg;
|
||||
|
|
|
@ -88,9 +88,10 @@
|
|||
}
|
||||
}
|
||||
.emoji-picker-panel {
|
||||
position: absolute;
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
margin-top: 2px;
|
||||
top: 0px !important;
|
||||
|
||||
&.hide {
|
||||
display: none
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
faStickyNote,
|
||||
faSmileBeam
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import { trim } from 'lodash'
|
||||
import { trim, escapeRegExp, startCase } from 'lodash'
|
||||
|
||||
library.add(
|
||||
faBoxOpen,
|
||||
|
@ -21,23 +21,6 @@ const LOAD_EMOJI_BY = 60
|
|||
// When to start loading new batch emoji, in pixels
|
||||
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 = {
|
||||
props: {
|
||||
enableStickerPicker: {
|
||||
|
@ -49,7 +32,7 @@ const EmojiPicker = {
|
|||
data () {
|
||||
return {
|
||||
keyword: '',
|
||||
activeGroup: 'custom',
|
||||
activeGroup: 'standard',
|
||||
showingStickers: false,
|
||||
groupsScrolledClass: 'scrolled-top',
|
||||
keepOpen: false,
|
||||
|
@ -80,13 +63,8 @@ const EmojiPicker = {
|
|||
this.triggerLoadMore(target)
|
||||
},
|
||||
highlight (key) {
|
||||
const ref = this.$refs['group-' + key]
|
||||
const top = ref.offsetTop
|
||||
this.setShowStickers(false)
|
||||
this.activeGroup = key
|
||||
this.$nextTick(() => {
|
||||
this.$refs['emoji-groups'].scrollTop = top + 1
|
||||
})
|
||||
},
|
||||
updateScrolledClass (target) {
|
||||
if (target.scrollTop <= 5) {
|
||||
|
@ -155,6 +133,13 @@ const EmojiPicker = {
|
|||
},
|
||||
setShowStickers (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: {
|
||||
|
@ -175,9 +160,8 @@ const EmojiPicker = {
|
|||
return 0
|
||||
},
|
||||
filteredEmoji () {
|
||||
return filterByKeyword(
|
||||
this.$store.state.instance.customEmoji || [],
|
||||
trim(this.keyword)
|
||||
return this.filterByKeyword(
|
||||
this.$store.state.instance.customEmoji || []
|
||||
)
|
||||
},
|
||||
customEmojiBuffer () {
|
||||
|
@ -185,25 +169,50 @@ const EmojiPicker = {
|
|||
},
|
||||
emojis () {
|
||||
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 [
|
||||
{
|
||||
id: 'custom',
|
||||
text: this.$t('emoji.custom'),
|
||||
icon: 'smile-beam',
|
||||
emojis: customEmojis
|
||||
},
|
||||
{
|
||||
id: 'standard',
|
||||
text: this.$t('emoji.unicode'),
|
||||
icon: 'box-open',
|
||||
emojis: filterByKeyword(standardEmojis, trim(this.keyword))
|
||||
first: {
|
||||
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 () {
|
||||
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 () {
|
||||
return (this.$store.state.instance.stickers || []).length !== 0
|
||||
|
|
|
@ -35,9 +35,12 @@
|
|||
}
|
||||
|
||||
.heading {
|
||||
display: flex;
|
||||
height: 32px;
|
||||
padding: 10px 7px 5px;
|
||||
margin-top: 10px;
|
||||
height: 5.8em;
|
||||
}
|
||||
|
||||
.emoji-header {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.content {
|
||||
|
@ -65,15 +68,34 @@
|
|||
|
||||
.additional-tabs,
|
||||
.emoji-tabs {
|
||||
position: absolute;
|
||||
display: block;
|
||||
min-width: 0;
|
||||
flex-basis: auto;
|
||||
flex-shrink: 1;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
&-item {
|
||||
padding: 0 7px;
|
||||
vertical-align: top;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: .4em;
|
||||
cursor: pointer;
|
||||
font-size: 1.85em;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 1.9em;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="emoji-picker panel panel-default panel-body">
|
||||
<div class="heading">
|
||||
<span class="emoji-header">Emoji Packs</span>
|
||||
<span class="emoji-tabs">
|
||||
<span
|
||||
v-for="group in emojis"
|
||||
|
@ -13,10 +14,11 @@
|
|||
:title="group.text"
|
||||
@click.prevent="highlight(group.id)"
|
||||
>
|
||||
<FAIcon
|
||||
:icon="group.icon"
|
||||
fixed-width
|
||||
/>
|
||||
<span v-if="!group.first.imageUrl">{{ group.first.replacement }}</span>
|
||||
<img
|
||||
v-else
|
||||
:src="group.first.imageUrl"
|
||||
>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
|
|
|
@ -27,7 +27,11 @@ const EmojiReactions = {
|
|||
},
|
||||
accountsForEmoji () {
|
||||
return this.status.emoji_reactions.reduce((acc, reaction) => {
|
||||
acc[reaction.name] = reaction.accounts || []
|
||||
if (reaction.url) {
|
||||
acc[reaction.url] = reaction.accounts || []
|
||||
} else {
|
||||
acc[reaction.name] = reaction.accounts || []
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
},
|
||||
|
@ -42,6 +46,14 @@ const EmojiReactions = {
|
|||
reactedWith (emoji) {
|
||||
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 () {
|
||||
const hasNoAccounts = this.status.emoji_reactions.find(r => !r.accounts)
|
||||
if (hasNoAccounts) {
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
<div class="emoji-reactions">
|
||||
<UserListPopover
|
||||
v-for="(reaction) in emojiReactions"
|
||||
:key="reaction.name"
|
||||
:users="accountsForEmoji[reaction.name]"
|
||||
:key="reaction.url || reaction.name"
|
||||
:users="accountsForEmoji[reaction.url || reaction.name]"
|
||||
>
|
||||
<button
|
||||
class="emoji-reaction btn button-default"
|
||||
:class="{ 'picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }"
|
||||
:disabled="!isLocalReaction(reaction.url)"
|
||||
@click="emojiOnClick(reaction.name, $event)"
|
||||
@mouseenter="fetchEmojiReactionsByIfMissing()"
|
||||
>
|
||||
|
@ -56,13 +57,15 @@
|
|||
}
|
||||
|
||||
.emoji-reaction {
|
||||
padding: 0 0.5em;
|
||||
padding: 1px 6px;
|
||||
margin-right: 0.5em;
|
||||
margin-top: 0.5em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
font-size: 0.7em !important;
|
||||
height: 30px;
|
||||
.reaction-emoji {
|
||||
width: 2.55em !important;
|
||||
margin-right: 0.25em;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Popover from '../popover/popover.vue'
|
||||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
faEllipsisH,
|
||||
|
@ -6,6 +7,7 @@ import {
|
|||
faEyeSlash,
|
||||
faThumbtack,
|
||||
faShareAlt,
|
||||
faQuoteLeft,
|
||||
faExternalLinkAlt
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import {
|
||||
|
@ -20,20 +22,48 @@ library.add(
|
|||
faEyeSlash,
|
||||
faThumbtack,
|
||||
faShareAlt,
|
||||
faQuoteLeft,
|
||||
faExternalLinkAlt,
|
||||
faFlag
|
||||
)
|
||||
|
||||
const ExtraButtons = {
|
||||
props: [ 'status' ],
|
||||
components: { Popover },
|
||||
props: ['status'],
|
||||
components: {
|
||||
Popover,
|
||||
ConfirmModal
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
expanded: false,
|
||||
showingDeleteDialog: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
deleteStatus () {
|
||||
const confirmed = window.confirm(this.$t('status.delete_confirm'))
|
||||
if (confirmed) {
|
||||
this.$store.dispatch('deleteStatus', { id: this.status.id })
|
||||
if (this.shouldConfirmDelete) {
|
||||
this.showDeleteStatusConfirmDialog()
|
||||
} 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 () {
|
||||
this.$store.dispatch('pinStatus', this.status.id)
|
||||
.then(() => this.$emit('onSuccess'))
|
||||
|
@ -89,8 +119,18 @@ const ExtraButtons = {
|
|||
canMute () {
|
||||
return !!this.currentUser
|
||||
},
|
||||
canTranslate () {
|
||||
return this.$store.state.instance.translationEnabled === true
|
||||
},
|
||||
statusLink () {
|
||||
return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}`
|
||||
if (this.status.is_local) {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,28 @@
|
|||
:icon="['far', 'flag']"
|
||||
/><span>{{ $t("user_card.report") }}</span>
|
||||
</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>
|
||||
</template>
|
||||
<template v-slot:trigger>
|
||||
|
@ -125,6 +147,18 @@
|
|||
icon="ellipsis-h"
|
||||
/>
|
||||
</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>
|
||||
</Popover>
|
||||
</template>
|
||||
|
@ -151,4 +185,11 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 801px) {
|
||||
.extra-quote {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
.FavoriteButton {
|
||||
display: flex;
|
||||
margin-right: 5px;
|
||||
|
||||
> :first-child {
|
||||
padding: 10px;
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||
import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
|
||||
export default {
|
||||
props: ['relationship', 'user', 'labelFollowing', 'buttonClass'],
|
||||
components: {
|
||||
ConfirmModal
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
inProgress: false
|
||||
inProgress: false,
|
||||
showingConfirmUnfollow: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
shouldConfirmUnfollow () {
|
||||
return this.$store.getters.mergedConfig.modalOnUnfollow
|
||||
},
|
||||
isPressed () {
|
||||
return this.inProgress || this.relationship.following
|
||||
},
|
||||
|
@ -35,6 +43,12 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
showConfirmUnfollow () {
|
||||
this.showingConfirmUnfollow = true
|
||||
},
|
||||
hideConfirmUnfollow () {
|
||||
this.showingConfirmUnfollow = false
|
||||
},
|
||||
onClick () {
|
||||
this.relationship.following || this.relationship.requested ? this.unfollow() : this.follow()
|
||||
},
|
||||
|
@ -45,12 +59,21 @@ export default {
|
|||
})
|
||||
},
|
||||
unfollow () {
|
||||
if (this.shouldConfirmUnfollow) {
|
||||
this.showConfirmUnfollow()
|
||||
} else {
|
||||
this.doUnfollow()
|
||||
}
|
||||
},
|
||||
doUnfollow () {
|
||||
const store = this.$store
|
||||
this.inProgress = true
|
||||
requestUnfollow(this.relationship.id, store).then(() => {
|
||||
this.inProgress = false
|
||||
store.commit('removeStatus', { timeline: 'friends', userId: this.relationship.id })
|
||||
})
|
||||
|
||||
this.hideConfirmUnfollow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,27 @@
|
|||
@click="onClick"
|
||||
>
|
||||
{{ 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>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
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'
|
||||
|
||||
const FollowRequestCard = {
|
||||
props: ['user'],
|
||||
components: {
|
||||
BasicUserCard
|
||||
BasicUserCard,
|
||||
ConfirmModal
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
showingApproveConfirmDialog: false,
|
||||
showingDenyConfirmDialog: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
findFollowRequestNotificationId () {
|
||||
|
@ -13,7 +21,26 @@ const FollowRequestCard = {
|
|||
)
|
||||
return notif && notif.id
|
||||
},
|
||||
showApproveConfirmDialog () {
|
||||
this.showingApproveConfirmDialog = true
|
||||
},
|
||||
hideApproveConfirmDialog () {
|
||||
this.showingApproveConfirmDialog = false
|
||||
},
|
||||
showDenyConfirmDialog () {
|
||||
this.showingDenyConfirmDialog = true
|
||||
},
|
||||
hideDenyConfirmDialog () {
|
||||
this.showingDenyConfirmDialog = false
|
||||
},
|
||||
approveUser () {
|
||||
if (this.shouldConfirmApprove) {
|
||||
this.showApproveConfirmDialog()
|
||||
} else {
|
||||
this.doApprove()
|
||||
}
|
||||
},
|
||||
doApprove () {
|
||||
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
|
||||
this.$store.dispatch('removeFollowRequest', this.user)
|
||||
|
||||
|
@ -25,14 +52,34 @@ const FollowRequestCard = {
|
|||
notification.type = 'follow'
|
||||
}
|
||||
})
|
||||
this.hideApproveConfirmDialog()
|
||||
},
|
||||
denyUser () {
|
||||
if (this.shouldConfirmDeny) {
|
||||
this.showDenyConfirmDialog()
|
||||
} else {
|
||||
this.doDeny()
|
||||
}
|
||||
},
|
||||
doDeny () {
|
||||
const notifId = this.findFollowRequestNotificationId()
|
||||
this.$store.state.api.backendInteractor.denyUser({ id: this.user.id })
|
||||
.then(() => {
|
||||
this.$store.dispatch('dismissNotificationLocal', { id: notifId })
|
||||
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') }}
|
||||
</button>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<template>
|
||||
<div>
|
||||
<FAIcon
|
||||
v-if="globeIcon"
|
||||
icon="globe"
|
||||
/>
|
||||
{{ ' ' }}
|
||||
<label for="interface-language-switcher">
|
||||
{{ promptText }}
|
||||
</label>
|
||||
|
@ -39,6 +44,10 @@ export default {
|
|||
setLanguage: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
globeIcon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -188,9 +188,21 @@ $modal-view-button-icon-margin: 0.5em;
|
|||
overflow-y: auto;
|
||||
min-height: 1em;
|
||||
max-width: 500px;
|
||||
max-height: 9.5em;
|
||||
word-break: break-word;
|
||||
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 {
|
||||
|
|
|
@ -15,11 +15,15 @@
|
|||
|
||||
.mention-avatar {
|
||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
vertical-align: middle;
|
||||
user-select: none;
|
||||
margin-right: 0.2em;
|
||||
|
||||
.still-image.avatar {
|
||||
border-radius: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.full {
|
||||
|
@ -113,3 +117,11 @@
|
|||
color: var(--faint, $fallback--faint);
|
||||
}
|
||||
}
|
||||
|
||||
.reply-glued-label {
|
||||
|
||||
.mention-avatar {
|
||||
width: 1.4em;
|
||||
height: 1.4em;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
@click.prevent="onClick"
|
||||
>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<UserAvatar
|
||||
v-if="shouldShowAvatar"
|
||||
class="mention-avatar"
|
||||
:user="user"
|
||||
/>
|
||||
<span class="shortName">@<span
|
||||
class="userName"
|
||||
v-html="userName"
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import SideDrawer from '../side_drawer/side_drawer.vue'
|
||||
import Notifications from '../notifications/notifications.vue'
|
||||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||
import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils'
|
||||
import GestureService from '../../services/gesture_service/gesture_service'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
faTimes,
|
||||
|
@ -18,11 +20,13 @@ library.add(
|
|||
const MobileNav = {
|
||||
components: {
|
||||
SideDrawer,
|
||||
Notifications
|
||||
Notifications,
|
||||
ConfirmModal
|
||||
},
|
||||
data: () => ({
|
||||
notificationsCloseGesture: undefined,
|
||||
notificationsOpen: false
|
||||
notificationsOpen: false,
|
||||
showingConfirmLogout: false
|
||||
}),
|
||||
created () {
|
||||
this.notificationsCloseGesture = GestureService.swipeGesture(
|
||||
|
@ -41,8 +45,17 @@ const MobileNav = {
|
|||
unseenNotificationsCount () {
|
||||
return this.unseenNotifications.length
|
||||
},
|
||||
hideSitename () { return this.$store.state.instance.hideSitename },
|
||||
sitename () { return this.$store.state.instance.name }
|
||||
mergedConfig () {
|
||||
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: {
|
||||
toggleMobileSidebar () {
|
||||
|
@ -68,9 +81,23 @@ const MobileNav = {
|
|||
scrollToTop () {
|
||||
window.scrollTo(0, 0)
|
||||
},
|
||||
showConfirmLogout () {
|
||||
this.showingConfirmLogout = true
|
||||
},
|
||||
hideConfirmLogout () {
|
||||
this.showingConfirmLogout = false
|
||||
},
|
||||
logout () {
|
||||
if (!this.shouldConfirmLogout) {
|
||||
this.doLogout()
|
||||
} else {
|
||||
this.showConfirmLogout()
|
||||
}
|
||||
},
|
||||
doLogout () {
|
||||
this.$router.replace('/main/public')
|
||||
this.$store.dispatch('logout')
|
||||
this.hideConfirmLogout()
|
||||
},
|
||||
markNotificationsAsSeen () {
|
||||
// this.$refs.notifications.markAsSeen()
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
/>
|
||||
</button>
|
||||
<router-link
|
||||
v-if="!hideSitename"
|
||||
v-if="!hideSiteName"
|
||||
class="site-name"
|
||||
:to="{ name: 'root' }"
|
||||
active-class="home"
|
||||
|
@ -76,6 +76,18 @@
|
|||
ref="sideDrawer"
|
||||
: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>
|
||||
</template>
|
||||
|
||||
|
@ -206,6 +218,14 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.confirm-modal.dark-overlay {
|
||||
&::before {
|
||||
z-index: 3000;
|
||||
}
|
||||
.dialog-modal.panel {
|
||||
z-index: 3001;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="federationPolicy"
|
||||
v-if="hasInstanceSpecificPolicies"
|
||||
class="mrf-transparency-panel"
|
||||
>
|
||||
<div class="panel panel-default base01-background">
|
||||
|
@ -65,7 +65,7 @@
|
|||
v-for="entry in rejectInstances"
|
||||
:key="entry.instance + '_reject'"
|
||||
>
|
||||
<td>{{ entry.instance }}</td>
|
||||
<td>{{ entry.instance.replace(/[aeiou](?=.*\.)/gi, '*') }}</td>
|
||||
<td v-if="entry.reason === ''">
|
||||
{{ $t("about.mrf.simple.not_applicable") }}
|
||||
</td>
|
||||
|
@ -76,7 +76,7 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<div v-if="quarantineInstances.length">
|
||||
<!--<div v-if="quarantineInstances.length">
|
||||
<h4>{{ $t("about.mrf.simple.quarantine") }}</h4>
|
||||
|
||||
<p>{{ $t("about.mrf.simple.quarantine_desc") }}</p>
|
||||
|
@ -90,7 +90,7 @@
|
|||
v-for="entry in quarantineInstances"
|
||||
:key="entry.instance + '_quarantine'"
|
||||
>
|
||||
<td>{{ entry.instance }}</td>
|
||||
<td>{{ entry.instance.replace(/[aeiou](?=.*\.)/gi, '*') }}</td>
|
||||
<td v-if="entry.reason === ''">
|
||||
{{ $t("about.mrf.simple.not_applicable") }}
|
||||
</td>
|
||||
|
@ -99,7 +99,7 @@
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>-->
|
||||
|
||||
<div v-if="ftlRemovalInstances.length">
|
||||
<h4>{{ $t("about.mrf.simple.ftl_removal") }}</h4>
|
||||
|
@ -115,7 +115,7 @@
|
|||
v-for="entry in ftlRemovalInstances"
|
||||
:key="entry.instance + '_ftl_removal'"
|
||||
>
|
||||
<td>{{ entry.instance }}</td>
|
||||
<td>{{ entry.instance.replace(/[aeiou](?=.*\.)/gi, '*') }}</td>
|
||||
<td v-if="entry.reason === ''">
|
||||
{{ $t("about.mrf.simple.not_applicable") }}
|
||||
</td>
|
||||
|
@ -140,7 +140,7 @@
|
|||
v-for="entry in mediaNsfwInstances"
|
||||
:key="entry.instance + '_media_nsfw'"
|
||||
>
|
||||
<td>{{ entry.instance }}</td>
|
||||
<td>{{ entry.instance.replace(/[aeiou](?=.*\.)/gi, '*') }}</td>
|
||||
<td v-if="entry.reason === ''">
|
||||
{{ $t("about.mrf.simple.not_applicable") }}
|
||||
</td>
|
||||
|
@ -165,7 +165,7 @@
|
|||
v-for="entry in mediaRemovalInstances"
|
||||
:key="entry.instance + '_media_removal'"
|
||||
>
|
||||
<td>{{ entry.instance }}</td>
|
||||
<td>{{ entry.instance.replace(/[aeiou](?=.*\.)/gi, '*') }}</td>
|
||||
<td v-if="entry.reason === ''">
|
||||
{{ $t("about.mrf.simple.not_applicable") }}
|
||||
</td>
|
||||
|
@ -176,7 +176,7 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<h2 v-if="hasKeywordPolicies">
|
||||
<!--<h2 v-if="hasKeywordPolicies">
|
||||
{{ $t("about.mrf.keyword.keyword_policies") }}
|
||||
</h2>
|
||||
|
||||
|
@ -217,7 +217,7 @@
|
|||
{{ keyword.replacement }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
faChevronDown,
|
||||
faChevronUp,
|
||||
faComments,
|
||||
faBell,
|
||||
faBolt,
|
||||
faInfoCircle,
|
||||
faStream,
|
||||
faList,
|
||||
|
@ -25,7 +25,7 @@ library.add(
|
|||
faChevronDown,
|
||||
faChevronUp,
|
||||
faComments,
|
||||
faBell,
|
||||
faBolt,
|
||||
faInfoCircle,
|
||||
faStream,
|
||||
faList,
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<FAIcon
|
||||
fixed-width
|
||||
class="fa-scale-110"
|
||||
icon="bell"
|
||||
icon="bolt"
|
||||
/>{{ $t("nav.interactions") }}
|
||||
</router-link>
|
||||
</li>
|
||||
|
|
|
@ -5,6 +5,7 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
|
|||
import UserCard from '../user_card/user_card.vue'
|
||||
import Timeago from '../timeago/timeago.vue'
|
||||
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 { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
|
||||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||
|
@ -36,7 +37,9 @@ const Notification = {
|
|||
return {
|
||||
userExpanded: false,
|
||||
betterShadow: this.$store.state.interface.browserSupport.cssFilter,
|
||||
unmuted: false
|
||||
unmuted: false,
|
||||
showingApproveConfirmDialog: false,
|
||||
showingDenyConfirmDialog: false
|
||||
}
|
||||
},
|
||||
props: [ 'notification' ],
|
||||
|
@ -46,7 +49,8 @@ const Notification = {
|
|||
UserCard,
|
||||
Timeago,
|
||||
Status,
|
||||
RichContent
|
||||
RichContent,
|
||||
ConfirmModal
|
||||
},
|
||||
methods: {
|
||||
toggleUserExpanded () {
|
||||
|
@ -61,7 +65,26 @@ const Notification = {
|
|||
toggleMute () {
|
||||
this.unmuted = !this.unmuted
|
||||
},
|
||||
showApproveConfirmDialog () {
|
||||
this.showingApproveConfirmDialog = true
|
||||
},
|
||||
hideApproveConfirmDialog () {
|
||||
this.showingApproveConfirmDialog = false
|
||||
},
|
||||
showDenyConfirmDialog () {
|
||||
this.showingDenyConfirmDialog = true
|
||||
},
|
||||
hideDenyConfirmDialog () {
|
||||
this.showingDenyConfirmDialog = false
|
||||
},
|
||||
approveUser () {
|
||||
if (this.shouldConfirmApprove) {
|
||||
this.showApproveConfirmDialog()
|
||||
} else {
|
||||
this.doApprove()
|
||||
}
|
||||
},
|
||||
doApprove () {
|
||||
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
|
||||
this.$store.dispatch('removeFollowRequest', this.user)
|
||||
this.$store.dispatch('markSingleNotificationAsSeen', { id: this.notification.id })
|
||||
|
@ -71,13 +94,22 @@ const Notification = {
|
|||
notification.type = 'follow'
|
||||
}
|
||||
})
|
||||
this.hideApproveConfirmDialog()
|
||||
},
|
||||
denyUser () {
|
||||
if (this.shouldConfirmDeny) {
|
||||
this.showDenyConfirmDialog()
|
||||
} else {
|
||||
this.doDeny()
|
||||
}
|
||||
},
|
||||
doDeny () {
|
||||
this.$store.state.api.backendInteractor.denyUser({ id: this.user.id })
|
||||
.then(() => {
|
||||
this.$store.dispatch('dismissNotificationLocal', { id: this.notification.id })
|
||||
this.$store.dispatch('removeFollowRequest', this.user)
|
||||
})
|
||||
this.hideDenyConfirmDialog()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -107,6 +139,15 @@ const Notification = {
|
|||
isStatusNotification () {
|
||||
return isStatusNotification(this.notification.type)
|
||||
},
|
||||
mergedConfig () {
|
||||
return this.$store.getters.mergedConfig
|
||||
},
|
||||
shouldConfirmApprove () {
|
||||
return this.mergedConfig.modalOnApproveFollow
|
||||
},
|
||||
shouldConfirmDeny () {
|
||||
return this.mergedConfig.modalOnDenyFollow
|
||||
},
|
||||
...mapState({
|
||||
currentUser: state => state.users.currentUser
|
||||
})
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
@import '../../_variables.scss';
|
||||
|
||||
.notification-reaction-emoji {
|
||||
width: 40px;
|
||||
display: flex;
|
||||
width: 32px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// TODO Copypaste from Status, should unify it somehow
|
||||
|
|
|
@ -230,6 +230,28 @@
|
|||
</template>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
:key="unit"
|
||||
:value="unit"
|
||||
>
|
||||
{{ $t(`time.unit.${unit}_short`, ['']) }}
|
||||
{{ $tc(`time.unit.${unit}_short`, expiryAmount, ['']) }}
|
||||
</option>
|
||||
</Select>
|
||||
</div>
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
.QuoteButton {
|
||||
display: flex;
|
||||
margin-left: -5px;
|
||||
|
||||
> :first-child {
|
||||
padding: 10px;
|
||||
|
@ -44,4 +45,10 @@
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
.QuoteButton {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -64,11 +64,11 @@
|
|||
|
||||
color: $fallback--text;
|
||||
color: var(--text, $fallback--text);
|
||||
border-style: solid;
|
||||
border-style: dashed;
|
||||
border-width: 1px;
|
||||
border-radius: $fallback--attachmentRadius;
|
||||
border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
border-color: $fallback--cBlue;
|
||||
border-color: var(--cBlue, $fallback--cBlue);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { faRetweet } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
|
@ -5,13 +6,24 @@ library.add(faRetweet)
|
|||
|
||||
const RetweetButton = {
|
||||
props: ['status', 'loggedIn', 'visibility'],
|
||||
components: {
|
||||
ConfirmModal
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
animated: false
|
||||
animated: false,
|
||||
showingConfirmDialog: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
retweet () {
|
||||
if (!this.status.repeated && this.shouldConfirmRepeat) {
|
||||
this.showConfirmDialog()
|
||||
} else {
|
||||
this.doRetweet()
|
||||
}
|
||||
},
|
||||
doRetweet () {
|
||||
if (!this.status.repeated) {
|
||||
this.$store.dispatch('retweet', { id: this.status.id })
|
||||
} else {
|
||||
|
@ -21,6 +33,13 @@ const RetweetButton = {
|
|||
setTimeout(() => {
|
||||
this.animated = false
|
||||
}, 500)
|
||||
this.hideConfirmDialog()
|
||||
},
|
||||
showConfirmDialog () {
|
||||
this.showingConfirmDialog = true
|
||||
},
|
||||
hideConfirmDialog () {
|
||||
this.showingConfirmDialog = false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -29,6 +48,9 @@ const RetweetButton = {
|
|||
},
|
||||
mergedConfig () {
|
||||
return this.$store.getters.mergedConfig
|
||||
},
|
||||
shouldConfirmRepeat () {
|
||||
return this.mergedConfig.modalOnRepeat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,18 @@
|
|||
>
|
||||
{{ status.repeat_num }}
|
||||
</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>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -124,6 +124,14 @@ export default {
|
|||
}
|
||||
|
||||
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, {
|
||||
mangle: false,
|
||||
gfm: false,
|
||||
|
@ -133,20 +141,22 @@ export default {
|
|||
mfmHtml.innerHTML = marked.parse(content)
|
||||
|
||||
// Add options with set values to CSS
|
||||
Array.from(mfmHtml.content.firstChild.getElementsByClassName('mfm')).map((el) => {
|
||||
if (el.dataset.speed) {
|
||||
el.style.animationDuration = el.dataset.speed
|
||||
}
|
||||
if (el.dataset.deg) {
|
||||
el.style.transform = `rotate(${el.dataset.deg}deg)`
|
||||
}
|
||||
if (Array.from(el.classList).includes('_mfm_font_')) {
|
||||
const font = Object.keys(el.dataset)[0]
|
||||
if (['serif', 'monospace', 'cursive', 'fantasy', 'emoji', 'math'].includes(font)) {
|
||||
el.style.fontFamily = font
|
||||
if (mfmHtml.content.firstChild) {
|
||||
Array.from(mfmHtml.content.firstChild.getElementsByClassName('mfm')).map((el) => {
|
||||
if (el.dataset.speed) {
|
||||
el.style.animationDuration = el.dataset.speed
|
||||
}
|
||||
}
|
||||
})
|
||||
if (el.dataset.deg) {
|
||||
el.style.transform = `rotate(${el.dataset.deg}deg)`
|
||||
}
|
||||
if (Array.from(el.classList).includes('_mfm_font_')) {
|
||||
const font = Object.keys(el.dataset)[0]
|
||||
if (['serif', 'monospace', 'cursive', 'fantasy', 'emoji', 'math'].includes(font)) {
|
||||
el.style.fontFamily = font
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return mfmHtml.innerHTML
|
||||
}
|
||||
|
@ -359,8 +369,6 @@ export const preProcessPerLine = (html, greentext) => {
|
|||
.trim()
|
||||
if (cleanedString.startsWith('>')) {
|
||||
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 {
|
||||
faEnvelope,
|
||||
faLock,
|
||||
faBiohazard,
|
||||
faLockOpen,
|
||||
faGlobe
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
@ -9,6 +10,7 @@ import {
|
|||
library.add(
|
||||
faEnvelope,
|
||||
faGlobe,
|
||||
faBiohazard,
|
||||
faLock,
|
||||
faLockOpen
|
||||
)
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
@click="changeVis('local')"
|
||||
>
|
||||
<FAIcon
|
||||
icon="users"
|
||||
icon="biohazard"
|
||||
class="fa-scale-110 fa-old-padding"
|
||||
/>
|
||||
</button>
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
faTimes,
|
||||
faFileUpload,
|
||||
faFileDownload,
|
||||
faSignOutAlt,
|
||||
faChevronDown
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import {
|
||||
|
@ -28,6 +29,7 @@ library.add(
|
|||
faWindowMinimize,
|
||||
faFileUpload,
|
||||
faFileDownload,
|
||||
faSignOutAlt,
|
||||
faChevronDown
|
||||
)
|
||||
|
||||
|
@ -66,6 +68,11 @@ const SettingsModal = {
|
|||
closeModal () {
|
||||
this.$store.dispatch('closeSettingsModal')
|
||||
},
|
||||
logout () {
|
||||
this.$router.replace('/main/public')
|
||||
this.$store.dispatch('closeSettingsModal')
|
||||
this.$store.dispatch('logout')
|
||||
},
|
||||
peekModal () {
|
||||
this.$store.dispatch('togglePeekSettingsModal')
|
||||
},
|
||||
|
@ -150,6 +157,7 @@ const SettingsModal = {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
currentUser () { return this.$store.state.users.currentUser },
|
||||
currentSaveStateNotice () {
|
||||
return this.$store.state.interface.settings.currentSaveStateNotice
|
||||
},
|
||||
|
|
|
@ -71,5 +71,11 @@
|
|||
display: flex;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.logout-button {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,20 @@
|
|||
id="unscrolled-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>
|
||||
</Modal>
|
||||
|
|
|
@ -37,6 +37,15 @@
|
|||
{{ $t('settings.hide_muted_posts') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
v-if="user"
|
||||
:disabled="hideFilteredStatuses"
|
||||
path="hideThreadsWithBlockedUsers"
|
||||
>
|
||||
{{ $t('settings.hide_threads_with_blocked_users') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
|
|
|
@ -50,6 +50,7 @@ const GeneralTab = {
|
|||
Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'webkitAudioDecodedByteCount') ||
|
||||
// Future spec, still not supported in Nightly 63 as of 08/2018
|
||||
Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'audioTracks')
|
||||
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
@ -82,11 +83,20 @@ const GeneralTab = {
|
|||
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()
|
||||
},
|
||||
methods: {
|
||||
changeDefaultScope (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') }}
|
||||
</BooleanSetting>
|
||||
</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>
|
||||
<BooleanSetting path="stopGifs">
|
||||
{{ $t('settings.stop_gifs') }}
|
||||
|
@ -103,6 +135,28 @@
|
|||
<BooleanSetting path="renderMisskeyMarkdown">
|
||||
{{ $t('settings.render_mfm') }}
|
||||
</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>
|
||||
<BooleanSetting
|
||||
|
@ -120,6 +174,77 @@
|
|||
{{ $t('settings.autohide_floating_post_button') }}
|
||||
</BooleanSetting>
|
||||
</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>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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 VersionTab = {
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
faSignOutAlt,
|
||||
faHome,
|
||||
faComments,
|
||||
faBell,
|
||||
faBolt,
|
||||
faUserPlus,
|
||||
faBullhorn,
|
||||
faSearch,
|
||||
|
@ -23,7 +23,7 @@ library.add(
|
|||
faSignOutAlt,
|
||||
faHome,
|
||||
faComments,
|
||||
faBell,
|
||||
faBolt,
|
||||
faUserPlus,
|
||||
faBullhorn,
|
||||
faSearch,
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
<FAIcon
|
||||
fixed-width
|
||||
class="fa-scale-110 fa-old-padding"
|
||||
icon="bell"
|
||||
icon="bolt"
|
||||
/> {{ $t("nav.interactions") }}
|
||||
</router-link>
|
||||
</li>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
:key="group.role"
|
||||
class="staff-group"
|
||||
>
|
||||
<h4>{{ $t('general.role.' + group.role) }}</h4>
|
||||
<h4>The Admin Team</h4>
|
||||
<basic-user-card
|
||||
v-for="user in group.users"
|
||||
:key="user.screen_name"
|
||||
|
@ -30,10 +30,21 @@
|
|||
|
||||
.staff-group {
|
||||
padding-left: 1em;
|
||||
padding-top: 1em;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 2px;
|
||||
|
||||
.basic-user-card {
|
||||
padding: 0.6em 0.4em;
|
||||
padding-left: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.basic-user-card-collapsed-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.still-image {
|
||||
border-radius: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import {
|
|||
faStar,
|
||||
faEyeSlash,
|
||||
faEye,
|
||||
faBiohazard,
|
||||
faThumbtack,
|
||||
faChevronUp,
|
||||
faChevronDown,
|
||||
|
@ -56,6 +57,7 @@ library.add(
|
|||
faEllipsisH,
|
||||
faEyeSlash,
|
||||
faEye,
|
||||
faBiohazard,
|
||||
faThumbtack,
|
||||
faChevronUp,
|
||||
faChevronDown,
|
||||
|
@ -261,6 +263,38 @@ const Status = {
|
|||
hasMentionsLine () {
|
||||
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 () {
|
||||
if (this.statusoid.user.id === this.currentUser.id) return false
|
||||
const reasonsToMute = this.userIsMuted ||
|
||||
|
@ -269,7 +303,11 @@ const Status = {
|
|||
// Wordfiltered
|
||||
this.muteWordHits.length > 0 ||
|
||||
// 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
|
||||
},
|
||||
userIsMuted () {
|
||||
|
@ -312,6 +350,9 @@ const Status = {
|
|||
hideFilteredStatuses () {
|
||||
return this.mergedConfig.hideFilteredStatuses
|
||||
},
|
||||
hideThreadsWithBlockedUsers () {
|
||||
return this.mergedConfig.hideThreadsWithBlockedUsers
|
||||
},
|
||||
hideWordFilteredPosts () {
|
||||
return this.mergedConfig.hideWordFilteredPosts
|
||||
},
|
||||
|
@ -319,8 +360,9 @@ const Status = {
|
|||
return (!this.shouldNotMute) && (
|
||||
(this.muted && this.hideFilteredStatuses) ||
|
||||
(this.userIsMuted && this.hideMutedUsers) ||
|
||||
(this.status.thread_muted && this.hideMutedThreads) ||
|
||||
(this.muteWordHits.length > 0 && this.hideWordFilteredPosts)
|
||||
((this.status.thread_muted || this.mentionsMutedUser) && this.hideMutedThreads) ||
|
||||
(this.muteWordHits.length > 0 && this.hideWordFilteredPosts) ||
|
||||
(this.mentionsBlockedUser && this.hideThreadsWithBlockedUsers)
|
||||
)
|
||||
},
|
||||
isFocused () {
|
||||
|
@ -409,7 +451,7 @@ const Status = {
|
|||
case 'direct':
|
||||
return 'envelope'
|
||||
case 'local':
|
||||
return 'users'
|
||||
return 'biohazard'
|
||||
default:
|
||||
return 'globe'
|
||||
}
|
||||
|
|
|
@ -453,6 +453,7 @@
|
|||
:status="status"
|
||||
@onError="showError"
|
||||
@onSuccess="clearError"
|
||||
@quote-toggle="toggleQuoting"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,10 +4,20 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.translation {
|
||||
border: 1px solid var(--accent, $fallback--link);
|
||||
border-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
margin-top: 1em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
.emoji {
|
||||
--_still_image-label-scale: 0.5;
|
||||
--emoji-size: 50px;
|
||||
--emoji-size: 50px;
|
||||
--emoji-size: 38px;
|
||||
}
|
||||
|
||||
.emoji:hover {
|
||||
transform: scale(1.4);
|
||||
transition: 0.05s;
|
||||
}
|
||||
|
||||
._mfm_x2_ {
|
||||
|
@ -93,7 +103,7 @@
|
|||
overflow-y: hidden;
|
||||
z-index: 1;
|
||||
|
||||
.media-body {
|
||||
.media-body-wrapper {
|
||||
min-height: 0;
|
||||
mask:
|
||||
linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat,
|
||||
|
@ -143,26 +153,25 @@
|
|||
color: var(--postGreentext, $fallback--cGreen);
|
||||
}
|
||||
|
||||
.cyantext {
|
||||
color: var(--postCyantext, $fallback--cBlue);
|
||||
}
|
||||
|
||||
&.-compact {
|
||||
align-items: top;
|
||||
flex-direction: row;
|
||||
|
||||
--emoji-size: 16px;
|
||||
|
||||
& .body,
|
||||
& .body:not(:active),
|
||||
& .attachments {
|
||||
max-height: 3.25em;
|
||||
}
|
||||
|
||||
.body {
|
||||
overflow: hidden;
|
||||
white-space: normal;
|
||||
min-width: 5em;
|
||||
flex: 5 1 auto;
|
||||
}
|
||||
|
||||
.body:not(:active) {
|
||||
overflow: hidden;
|
||||
mask-size: auto 3.5em, auto auto;
|
||||
mask-position: 0 0, 0 0;
|
||||
mask-repeat: repeat-x, repeat;
|
||||
|
@ -197,3 +206,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
</button>
|
||||
<div
|
||||
v-if="!hideSubjectStatus && !(singleLine && status.summary_raw_html)"
|
||||
class="media-body-wrapper"
|
||||
>
|
||||
<RichContent
|
||||
:class="{ '-single-line': singleLine }"
|
||||
|
@ -55,6 +56,23 @@
|
|||
:attentions="status.attentions"
|
||||
@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>
|
||||
<button
|
||||
v-show="hideSubjectStatus"
|
||||
|
|
|
@ -100,6 +100,9 @@ const StatusContent = {
|
|||
maxThumbnails () {
|
||||
return this.mergedConfig.maxThumbnails
|
||||
},
|
||||
mfmOnHover () {
|
||||
return this.mergedConfig.mfmOnHover
|
||||
},
|
||||
...mapGetters(['mergedConfig']),
|
||||
...mapState({
|
||||
currentUser: state => state.users.currentUser
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div
|
||||
class="StatusContent"
|
||||
:class="{ '-compact': compact }"
|
||||
:class="{ '-compact': compact, 'mfm-hover': mfmOnHover }"
|
||||
>
|
||||
<slot name="header" />
|
||||
<StatusBody
|
||||
|
@ -75,5 +75,17 @@
|
|||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
&.mfm-hover:not(:hover) {
|
||||
.mfm {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.quote-inline,
|
||||
.quote + .link-preview {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -51,6 +51,10 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
|
||||
&::before {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&.animated {
|
||||
|
|
|
@ -58,7 +58,9 @@ export default {
|
|||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
time.warning {
|
||||
color: var(--alertWarning, $fallback--alertWarning);
|
||||
.timeago {
|
||||
time.warning {
|
||||
color: var(--alertWarning, $fallback--alertWarning);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
faBookmark,
|
||||
faEnvelope,
|
||||
faHome,
|
||||
faCircle
|
||||
faCommentMedical
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
library.add(
|
||||
|
@ -15,7 +15,7 @@ library.add(
|
|||
faBookmark,
|
||||
faEnvelope,
|
||||
faHome,
|
||||
faCircle
|
||||
faCommentMedical
|
||||
)
|
||||
|
||||
const TimelineMenuContent = {
|
||||
|
|
|
@ -9,22 +9,8 @@
|
|||
fixed-width
|
||||
class="fa-scale-110 fa-old-padding "
|
||||
icon="home"
|
||||
/>{{ $t("nav.home_timeline") }}
|
||||
/><span :title="$t('nav.home_timeline_description')">{{ $t("nav.home_timeline") }}</span>
|
||||
</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 v-if="currentUser || !privateMode">
|
||||
<router-link
|
||||
|
@ -35,9 +21,8 @@
|
|||
fixed-width
|
||||
class="fa-scale-110 fa-old-padding "
|
||||
icon="users"
|
||||
/>{{ $t("nav.public_tl") }}
|
||||
/><span :title="$t('nav.public_timeline_description')">{{ $t("nav.public_tl") }}</span>
|
||||
</router-link>
|
||||
<span class="timeline-desc">{{ $t("nav.public_timeline_description") }}</span>
|
||||
</li>
|
||||
<li v-if="federating && (currentUser || !privateMode)">
|
||||
<router-link
|
||||
|
@ -48,9 +33,20 @@
|
|||
fixed-width
|
||||
class="fa-scale-110 fa-old-padding "
|
||||
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>
|
||||
<span class="timeline-desc">{{ $t("nav.twkn_timeline_description") }}</span>
|
||||
</li>
|
||||
<li v-if="currentUser">
|
||||
<router-link
|
||||
|
|
|
@ -6,6 +6,7 @@ import ModerationTools from '../moderation_tools/moderation_tools.vue'
|
|||
import AccountActions from '../account_actions/account_actions.vue'
|
||||
import Select from '../select/select.vue'
|
||||
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 { mapGetters } from 'vuex'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
|
@ -32,7 +33,8 @@ export default {
|
|||
data () {
|
||||
return {
|
||||
followRequestInProgress: false,
|
||||
betterShadow: this.$store.state.interface.browserSupport.cssFilter
|
||||
betterShadow: this.$store.state.interface.browserSupport.cssFilter,
|
||||
showingConfirmMute: false
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
@ -112,6 +114,9 @@ export default {
|
|||
hideFollowersCount () {
|
||||
return this.isOtherUser && this.user.hide_followers_count
|
||||
},
|
||||
shouldConfirmMute () {
|
||||
return this.mergedConfig.modalOnMute
|
||||
},
|
||||
...mapGetters(['mergedConfig'])
|
||||
},
|
||||
components: {
|
||||
|
@ -122,14 +127,29 @@ export default {
|
|||
ProgressButton,
|
||||
FollowButton,
|
||||
Select,
|
||||
RichContent
|
||||
RichContent,
|
||||
ConfirmModal
|
||||
},
|
||||
methods: {
|
||||
refetchRelationship () {
|
||||
return this.$store.dispatch('fetchUserRelationship', this.user.id)
|
||||
},
|
||||
showConfirmMute () {
|
||||
this.showingConfirmMute = true
|
||||
},
|
||||
hideConfirmMute () {
|
||||
this.showingConfirmMute = false
|
||||
},
|
||||
muteUser () {
|
||||
if (!this.shouldConfirmMute) {
|
||||
this.doMuteUser()
|
||||
} else {
|
||||
this.showConfirmMute()
|
||||
}
|
||||
},
|
||||
doMuteUser () {
|
||||
this.$store.dispatch('muteUser', this.user.id)
|
||||
this.hideConfirmMute()
|
||||
},
|
||||
unmuteUser () {
|
||||
this.$store.dispatch('unmuteUser', this.user.id)
|
||||
|
|
|
@ -295,6 +295,27 @@
|
|||
:handle-links="true"
|
||||
/>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@ const UserProfile = {
|
|||
timeline () {
|
||||
return this.$store.state.statuses.timelines.user
|
||||
},
|
||||
replies () {
|
||||
return this.$store.state.statuses.timelines.replies
|
||||
},
|
||||
favorites () {
|
||||
return this.$store.state.statuses.timelines.favorites
|
||||
},
|
||||
|
@ -82,7 +85,8 @@ const UserProfile = {
|
|||
},
|
||||
currentUser () {
|
||||
return this.$store.state.users.currentUser
|
||||
}
|
||||
},
|
||||
privateMode () { return this.$store.state.instance.private }
|
||||
},
|
||||
methods: {
|
||||
setFooterRef (el) {
|
||||
|
@ -100,6 +104,7 @@ const UserProfile = {
|
|||
const loadById = (userId) => {
|
||||
this.userId = userId
|
||||
startFetchingTimeline('user', userId)
|
||||
startFetchingTimeline('replies', userId)
|
||||
startFetchingTimeline('media', userId)
|
||||
if (this.isUs) {
|
||||
startFetchingTimeline('favorites', userId)
|
||||
|
@ -137,6 +142,7 @@ const UserProfile = {
|
|||
},
|
||||
stopFetching () {
|
||||
this.$store.dispatch('stopFetchingTimeline', 'user')
|
||||
this.$store.dispatch('stopFetchingTimeline', 'replies')
|
||||
this.$store.dispatch('stopFetchingTimeline', 'favorites')
|
||||
this.$store.dispatch('stopFetchingTimeline', 'media')
|
||||
},
|
||||
|
|
|
@ -79,6 +79,18 @@
|
|||
:in-profile="true"
|
||||
:footer-slipgate="footerRef"
|
||||
/>
|
||||
<Timeline
|
||||
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
|
||||
v-if="followsTabVisible"
|
||||
key="followees"
|
||||
|
@ -136,6 +148,22 @@
|
|||
class="panel-footer"
|
||||
/>
|
||||
</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
|
||||
v-else
|
||||
class="panel user-profile-placeholder"
|
||||
|
@ -246,6 +274,15 @@
|
|||
justify-content: center;
|
||||
align-items: middle;
|
||||
padding: 7em;
|
||||
|
||||
&.error {
|
||||
padding: 0em;
|
||||
}
|
||||
|
||||
.error-img {
|
||||
width: 100%;
|
||||
border-radius: 0px 0px 10px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
374
src/i18n/ca.json
374
src/i18n/ca.json
|
@ -164,8 +164,8 @@
|
|||
"fullname_required": "no es pot deixar en blanc",
|
||||
"username_required": "no es pot deixar en blanc"
|
||||
},
|
||||
"fullname_placeholder": "p. ex. Anna Bofarull",
|
||||
"username_placeholder": "p. ex. anna",
|
||||
"fullname_placeholder": "p. ex. Lain Iwakura",
|
||||
"username_placeholder": "p. ex. lain",
|
||||
"captcha": "CAPTCHA",
|
||||
"register": "Registre",
|
||||
"reason": "Raó per a registrar-se",
|
||||
|
@ -181,99 +181,99 @@
|
|||
"avatarAltRadius": "Avatars (notificacions)",
|
||||
"avatarRadius": "Avatars",
|
||||
"background": "Fons de pantalla",
|
||||
"bio": "Presentació",
|
||||
"bio": "Bio",
|
||||
"btnRadius": "Botons",
|
||||
"cBlue": "Blau (respon, segueix)",
|
||||
"cGreen": "Verd (republica)",
|
||||
"cOrange": "Taronja (marca com a preferit)",
|
||||
"cOrange": "Taronja (afavoreix)",
|
||||
"cRed": "Vermell (canceŀla)",
|
||||
"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!",
|
||||
"collapse_subject": "Replega les entrades amb títol",
|
||||
"collapse_subject": "Replega els apunts amb assumpte",
|
||||
"confirm_new_password": "Confirma la nova contrasenya",
|
||||
"current_avatar": "L'avatar actual",
|
||||
"current_password": "La contrasenya actual",
|
||||
"current_avatar": "El teu avatar actual",
|
||||
"current_password": "Contrasenya actual",
|
||||
"current_profile_banner": "El fons de perfil actual",
|
||||
"data_import_export_tab": "Importa o exporta dades",
|
||||
"default_vis": "Abast per defecte de les entrades",
|
||||
"data_import_export_tab": "Importa dades / exporta",
|
||||
"default_vis": "Visibilitat per defecte dels apunts",
|
||||
"delete_account": "Esborra el 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_instructions": "Confirma que vols esborrar el compte escrivint la teva contrasenya aquí sota.",
|
||||
"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": "Escriu la teva contrasenya en el camp de sota per a confirmar esborrar el compte.",
|
||||
"export_theme": "Desa el tema",
|
||||
"filtering": "Filtres",
|
||||
"filtering_explanation": "Es silenciaran totes les entrades que continguin aquestes paraules. Separa-les per línies",
|
||||
"follow_export": "Exporta la llista de contactes",
|
||||
"follow_export_button": "Exporta tots els comptes que segueixes a un fitxer CSV",
|
||||
"filtering": "Filtrant",
|
||||
"filtering_explanation": "Es silenciaran tots els apunts que continguin aquestes paraules, una per línia",
|
||||
"follow_export": "Exporta els seguits",
|
||||
"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_import": "Importa els contactes",
|
||||
"follow_import_error": "No s'ha pogut importar els contactes",
|
||||
"follows_imported": "S'han importat els contactes. Trigaran una estoneta en ser processats.",
|
||||
"follow_import": "Importa els seguits",
|
||||
"follow_import_error": "Error al importar els seguidors",
|
||||
"follows_imported": "S'han importat els seguits! Processar-los portarà una estona.",
|
||||
"foreground": "Primer pla",
|
||||
"general": "General",
|
||||
"hide_attachments_in_convo": "Amaga els adjunts en les converses",
|
||||
"hide_attachments_in_tl": "Amaga els adjunts en el flux d'entrades",
|
||||
"import_followers_from_a_csv_file": "Importa els contactes des d'un fitxer CSV",
|
||||
"hide_attachments_in_tl": "Amaga els adjunts en la línia de temps",
|
||||
"import_followers_from_a_csv_file": "Importa els seguits des d'un fitxer CSV",
|
||||
"import_theme": "Carrega un tema",
|
||||
"inputRadius": "Caixes d'entrada de text",
|
||||
"inputRadius": "Camps d'entrada",
|
||||
"instance_default": "(default: {value})",
|
||||
"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.",
|
||||
"limited_availability": "No està disponible en aquest navegador",
|
||||
"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 el teu navegador",
|
||||
"links": "Enllaços",
|
||||
"lock_account_description": "Restringeix el teu compte només a seguidores aprovades",
|
||||
"loop_video": "Reprodueix els vídeos en bucle",
|
||||
"loop_video_silent_only": "Reprodueix en bucles només els vídeos sense so (com els \"GIF\" de Mastodon)",
|
||||
"lock_account_description": "Restringeix el teu compte només a seguidors aprovats",
|
||||
"loop_video": "Vídeos en bucle",
|
||||
"loop_video_silent_only": "Només bucle de vídeos sense so (com els \"GIF\" de Mastodon)",
|
||||
"name": "Nom",
|
||||
"name_bio": "Nom i presentació",
|
||||
"name_bio": "Nom i bio",
|
||||
"new_password": "Contrasenya nova",
|
||||
"notification_visibility": "Notifica'm quan algú",
|
||||
"notification_visibility_follows": "Comença a seguir-me",
|
||||
"notification_visibility_likes": "Favorits",
|
||||
"notification_visibility_mentions": "Em menciona",
|
||||
"notification_visibility_repeats": "Republica una entrada meva",
|
||||
"no_rich_text_description": "Neteja el formatat de text de totes les entrades",
|
||||
"nsfw_clickthrough": "Amaga el contingut NSFW darrer d'una imatge clicable",
|
||||
"oauth_tokens": "Llistats OAuth",
|
||||
"notification_visibility": "Tipus de notificacions a mostrar",
|
||||
"notification_visibility_follows": "Seguits",
|
||||
"notification_visibility_likes": "m'afavoreix",
|
||||
"notification_visibility_mentions": "em menciona",
|
||||
"notification_visibility_repeats": "em repeteix",
|
||||
"no_rich_text_description": "Neteja el format de text de tots els apunts",
|
||||
"nsfw_clickthrough": "Amaga els Mèdia sensibles/NSFW",
|
||||
"oauth_tokens": "Codis OAuth",
|
||||
"token": "Token",
|
||||
"refresh_token": "Actualitza el token",
|
||||
"valid_until": "Vàlid fins",
|
||||
"revoke_token": "Revocar",
|
||||
"revoke_token": "Revoca",
|
||||
"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",
|
||||
"profile_background": "Fons de pantalla",
|
||||
"profile_banner": "Fons de perfil",
|
||||
"profile_background": "Fons del perfil",
|
||||
"profile_banner": "Banner del perfil",
|
||||
"profile_tab": "Perfil",
|
||||
"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_following": "Mostra només les respostes a entrades meves o d'usuàries que jo segueixo",
|
||||
"reply_visibility_self": "Mostra només les respostes a entrades meves",
|
||||
"saving_err": "No s'ha pogut desar la configuració",
|
||||
"saving_ok": "S'ha desat la configuració",
|
||||
"reply_visibility_following": "Mostra només les respostes dirigides a mi o a usuaris que segueixo",
|
||||
"reply_visibility_self": "Mostra només les respostes dirigides a mi",
|
||||
"saving_err": "Error al desar la configuració",
|
||||
"saving_ok": "Configuració desada",
|
||||
"security_tab": "Seguretat",
|
||||
"set_new_avatar": "Canvia l'avatar",
|
||||
"set_new_profile_background": "Canvia el fons de pantalla",
|
||||
"set_new_profile_banner": "Canvia el fons del perfil",
|
||||
"set_new_avatar": "Establir un nou avatar",
|
||||
"set_new_profile_background": "Canvia el fons del perfil",
|
||||
"set_new_profile_banner": "Establir un nou banner del perfil",
|
||||
"settings": "Configuració",
|
||||
"stop_gifs": "Anima els GIF només en passar-hi el ratolí per sobre",
|
||||
"streaming": "Carrega automàticament entrades noves quan estigui a dalt de tot",
|
||||
"stop_gifs": "Anima les imatges animades fins que hi passis el cursor per sobre",
|
||||
"streaming": "Mostra automàticament els nous apunts quan et desplacis a la part superior",
|
||||
"text": "Text",
|
||||
"theme": "Tema",
|
||||
"theme_help": "Personalitza els colors del tema. Escriu-los en format RGB hexadecimal (#rrggbb).",
|
||||
"tooltipRadius": "Missatges sobreposats",
|
||||
"user_settings": "Configuració personal",
|
||||
"theme_help": "Utilitza els codis de color hex (#rrggbb) per a personalitzar el color del teu tema.",
|
||||
"tooltipRadius": "Globus/alertes",
|
||||
"user_settings": "Configuració d'usuari",
|
||||
"values": {
|
||||
"false": "no",
|
||||
"true": "sí"
|
||||
},
|
||||
"show_moderator_badge": "Mostra una insígnia de Moderació en el meu perfil",
|
||||
"show_admin_badge": "Mostra una insígnia \"d'Administració\" en el meu perfil",
|
||||
"show_moderator_badge": "Mostra l'insígnia \"Moderador\" 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_follows_description": "No mostris a qui segueixo",
|
||||
"notification_visibility_emoji_reactions": "Reaccions",
|
||||
"notification_visibility_emoji_reactions": "reacciona",
|
||||
"new_email": "Nou correu electrònic",
|
||||
"profile_fields": {
|
||||
"value": "Contingut",
|
||||
|
@ -281,69 +281,69 @@
|
|||
"add_field": "Afegeix un camp",
|
||||
"label": "Metadades del perfil"
|
||||
},
|
||||
"mutes_tab": "Silenciaments",
|
||||
"mutes_tab": "Silenciats",
|
||||
"interface": "Interfície",
|
||||
"instance_default_simple": "(per defecte)",
|
||||
"checkboxRadius": "Caselles",
|
||||
"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",
|
||||
"hide_muted_posts": "Amaga les entrades de comptes silenciats",
|
||||
"avatar_size_instruction": "La mida mínima recomanada per la imatge de l'avatar és de 150x150 píxels.",
|
||||
"hide_muted_posts": "Amaga els apunts de comptes silenciats",
|
||||
"avatar_size_instruction": "La mida mínima recomanada per les imatges dels avatars és de 150x150 píxels.",
|
||||
"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",
|
||||
"composing": "Composant",
|
||||
"chatMessageRadius": "Missatge de xat",
|
||||
"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": "Canvia el correu electrònic",
|
||||
"bot": "Aquest és un compte automatitzat",
|
||||
"bot": "Aquest és un compte bot",
|
||||
"blocks_tab": "Bloquejos",
|
||||
"blocks_imported": "Bloquejos importats! Processar-los pot trigar una mica.",
|
||||
"block_import_error": "Error al importar bloquejos",
|
||||
"block_import": "Importa bloquejos",
|
||||
"block_export_button": "Exporta els teus bloquejos a un arxiu csv",
|
||||
"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": {
|
||||
"scan": {
|
||||
"secret_code": "Clau",
|
||||
"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ó",
|
||||
"waiting_a_recovery_codes": "Rebent còpies de seguretat dels codis…",
|
||||
"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ó",
|
||||
"otp": "OTP",
|
||||
"confirm_and_enable": "Confirmar i habilitar 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.",
|
||||
"confirm_and_enable": "Confirma i habilita OTP",
|
||||
"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",
|
||||
"setup_otp": "Configurar OTP",
|
||||
"wait_pre_setup_otp": "preconfiguració OTP",
|
||||
"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",
|
||||
"app_name": "Nom de l'aplicació",
|
||||
"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",
|
||||
"mutes_imported": "Silenciats importats! Processar-los portarà una estona.",
|
||||
"import_mutes_from_a_csv_file": "Importar silenciats des d'un fitxer csv",
|
||||
"word_filter": "Filtre de paraules",
|
||||
"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",
|
||||
"file_export_import": {
|
||||
"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_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"
|
||||
},
|
||||
"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ó"
|
||||
},
|
||||
"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",
|
||||
"save": "Guardar els canvis",
|
||||
"save": "Desar els canvis",
|
||||
"use_contain_fit": "No retallar els adjunts en miniatures",
|
||||
"reset_profile_background": "Restablir fons del perfil",
|
||||
"reset_profile_banner": "Restablir banner del perfil",
|
||||
"emoji_reactions_on_timeline": "Mostrar reaccions emoji al flux",
|
||||
"max_thumbnails": "Quantitat màxima de miniatures per publicació",
|
||||
"hide_user_stats": "Amagar les estadístiques de l'usuari (p. ex. el nombre de seguidors)",
|
||||
"emoji_reactions_on_timeline": "Mostra reaccions emoji en la línia de temps",
|
||||
"max_thumbnails": "Quantitat màxima de miniatures per apunt (buit = sense limit)",
|
||||
"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_background_confirm": "Realment vols restablir el fons del perfil?",
|
||||
"subject_input_always_show": "Sempre mostrar el camp del tema",
|
||||
"reset_background_confirm": "Realment vols restablir el fons?",
|
||||
"subject_input_always_show": "Sempre mostrar el camp del assumpte",
|
||||
"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",
|
||||
"mute_export": "Exportar silenciats",
|
||||
"scope_copy": "Copiar visibilitat quan contestes (En els missatges directes sempre es copia)",
|
||||
"reset_avatar": "Restablir avatar",
|
||||
"right_sidebar": "Mostrar barra lateral a la dreta",
|
||||
"scope_copy": "Copiar visibilitat quan responguis (en els missatges directes sempre es copia)",
|
||||
"reset_avatar": "Restablir l'avatar",
|
||||
"right_sidebar": "Ordre invers de les columnes",
|
||||
"no_blocks": "No hi han bloquejats",
|
||||
"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",
|
||||
"hide_all_muted_posts": "Ocultar publicacions silenciades",
|
||||
"hide_all_muted_posts": "Ocultar apunts silenciades",
|
||||
"hide_wallpaper": "Amagar el fons de la instància",
|
||||
"notification_visibility_moves": "Usuari Migrat",
|
||||
"reply_visibility_following_short": "Mostrar respostes als meus seguidors",
|
||||
"reply_visibility_self_short": "Mostrar respostes només a un mateix",
|
||||
"autohide_floating_post_button": "Ocultar automàticament el botó 'Nova Publicació' (mòbil)",
|
||||
"minimal_scopes_mode": "Minimitzar les opcions de visibilitat de la publicació",
|
||||
"sensitive_by_default": "Marcar publicacions com a sensibles per defecte",
|
||||
"useStreamingApi": "Rebre publicacions i notificacions en temps real",
|
||||
"hide_isp": "Ocultar el panell especific de la instància",
|
||||
"notification_visibility_moves": "es mou",
|
||||
"reply_visibility_following_short": "Mostrar respostes als meus seguits",
|
||||
"reply_visibility_self_short": "Mostrar només respostes a mi mateix",
|
||||
"autohide_floating_post_button": "Ocultar automàticament el botó 'Nou Apunt' (mòbil)",
|
||||
"minimal_scopes_mode": "Minimitzar les opcions de selecció del abast del apunt",
|
||||
"sensitive_by_default": "Marcar apunts com a sensibles per defecte",
|
||||
"useStreamingApi": "Rebre apunts i notificacions en temps real",
|
||||
"hide_isp": "Amaga el panell especific de la instància",
|
||||
"preload_images": "Precarregar les imatges",
|
||||
"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?",
|
||||
"accent": "Accent",
|
||||
"useStreamingApiWarning": "És genial emprar-lo. Si es trenca, refresca, suposo?",
|
||||
|
@ -397,10 +397,10 @@
|
|||
"size": "Mida (en píxels)",
|
||||
"custom": "Personalitza",
|
||||
"_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": {
|
||||
"post": "Text de les publicacions",
|
||||
"postCode": "Text monoespai en publicació (text enriquit)",
|
||||
"post": "Text dels apunts",
|
||||
"postCode": "Text mono-espai en un apunt (text enriquit)",
|
||||
"input": "Camps d'entrada",
|
||||
"interface": "Interfície"
|
||||
},
|
||||
|
@ -418,19 +418,19 @@
|
|||
"checkbox": "He llegit els termes i condicions",
|
||||
"link": "un bonic enllaç",
|
||||
"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": {
|
||||
"spread": "Difon",
|
||||
"filter_hint": {
|
||||
"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.",
|
||||
"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.",
|
||||
"spread_zero": "Ombres amb propagació > 0 apareixeran com si estigueren posades a zero"
|
||||
},
|
||||
"components": {
|
||||
"popup": "Texts i finestres emergents (popups & tooltips)",
|
||||
"popup": "Globus i finestres emergents",
|
||||
"panel": "Panell",
|
||||
"panelHeader": "Capçalera del panell",
|
||||
"avatar": "Avatar de l'usuari (en vista de perfil)",
|
||||
|
@ -438,8 +438,8 @@
|
|||
"buttonHover": "Botó (surant)",
|
||||
"buttonPressed": "Botó (pressionat)",
|
||||
"topBar": "Barra superior",
|
||||
"buttonPressedHover": "Botó (surant i pressionat)",
|
||||
"avatarStatus": "Avatar de l'usuari (en vista de publicació)",
|
||||
"buttonPressedHover": "Botó (pressionat i surant)",
|
||||
"avatarStatus": "Avatar de l'usuari (en vista de apunt)",
|
||||
"button": "Botó"
|
||||
},
|
||||
"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.",
|
||||
"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.",
|
||||
"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.",
|
||||
"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.",
|
||||
"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.",
|
||||
"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."
|
||||
},
|
||||
"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_opacity": "Mantindre opacitat",
|
||||
"keep_shadows": "Mantindre ombres",
|
||||
"keep_fonts": "Mantindre fonts",
|
||||
"keep_roundness": "Mantindre rodoneses",
|
||||
"clear_all": "Netejar tot",
|
||||
"reset": "Reinciar",
|
||||
"reset": "Reiniciar",
|
||||
"load_theme": "Carregar tema",
|
||||
"use_source": "Nova versió",
|
||||
"clear_opacity": "Netejar opacitat"
|
||||
|
@ -482,9 +482,9 @@
|
|||
"contrast": {
|
||||
"hint": "El ràtio de contrast és {ratio}. {level} {context}",
|
||||
"level": {
|
||||
"bad": "no compleix amb cap pauta d'accecibilitat",
|
||||
"aaa": "Compleix amb el nivell AA (recomanat)",
|
||||
"aa": "Compleix amb el nivell AA (mínim)"
|
||||
"bad": "no compleix amb cap pauta d'accessibilitat",
|
||||
"aaa": "Compleix amb la guia del nivell AA (recomanat)",
|
||||
"aa": "Compleix amb la guia del nivell AA (mínim)"
|
||||
},
|
||||
"context": {
|
||||
"18pt": "per a textos grans (+18pt)",
|
||||
|
@ -501,8 +501,8 @@
|
|||
"pressed": "Pressionat",
|
||||
"chat": {
|
||||
"outgoing": "Eixint",
|
||||
"border": "Borde",
|
||||
"incoming": "Entrants"
|
||||
"border": "Vora",
|
||||
"incoming": "Entrant"
|
||||
},
|
||||
"borders": "Bordes",
|
||||
"panel_header": "Capçalera del panell",
|
||||
|
@ -512,8 +512,8 @@
|
|||
"toggled": "Commutat",
|
||||
"alert": "Fons d'alertes",
|
||||
"alert_error": "Error",
|
||||
"alert_warning": "Precaució",
|
||||
"post": "Publicacions/Biografies d'usuaris",
|
||||
"alert_warning": "Avís",
|
||||
"post": "Apunts/Bio d'usuari",
|
||||
"badge_notification": "Notificacions",
|
||||
"selectedMenu": "Element del menú seleccionat",
|
||||
"tabs": "Pestanyes",
|
||||
|
@ -524,7 +524,7 @@
|
|||
"highlight": "Elements destacats",
|
||||
"disabled": "Deshabilitat",
|
||||
"icons": "Icones",
|
||||
"selectedPost": "Publicació seleccionada",
|
||||
"selectedPost": "Apunt seleccionat",
|
||||
"underlay": "Subratllat"
|
||||
},
|
||||
"common_colors": {
|
||||
|
@ -538,32 +538,32 @@
|
|||
}
|
||||
},
|
||||
"version": {
|
||||
"frontend_version": "Versió \"Frontend\"",
|
||||
"backend_version": "Versió \"backend\"",
|
||||
"frontend_version": "Versió del \"Frontend\"",
|
||||
"backend_version": "Versió del \"backend\"",
|
||||
"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",
|
||||
"greentext": "Text verd (meme arrows)",
|
||||
"fun": "Divertit",
|
||||
"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",
|
||||
"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",
|
||||
"notification_setting_privacy": "Privacitat",
|
||||
"upload_a_photo": "Pujar una foto",
|
||||
"notification_setting_hide_notification_contents": "Amagar el remitent i els continguts de les notificacions push",
|
||||
"notifications": "Notificacions",
|
||||
"notification_mutes": "Per a deixar de rebre notificacions d'un usuari en concret, silencia'l-ho.",
|
||||
"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.",
|
||||
"hide_shoutbox": "Oculta la casella de gàbia de grills",
|
||||
"always_show_post_button": "Mostra sempre el botó flotant de publicació nova",
|
||||
"pad_emoji": "Acompanya els emojis amb espais en afegir des del selector",
|
||||
"notification_mutes": "Per a deixar de rebre notificacions d'un usuari en concret, silencia'l.",
|
||||
"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": "Amaga la casella de gàbia de grills",
|
||||
"always_show_post_button": "Mostra sempre el botó flotant d'Apunt Nou",
|
||||
"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_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",
|
||||
"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",
|
||||
|
@ -572,7 +572,7 @@
|
|||
"account_alias": "Àlies del compte",
|
||||
"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.",
|
||||
"hide_wordfiltered_statuses": "Amaga publicacions filtrades per paraules",
|
||||
"hide_wordfiltered_statuses": "Amaga apunts filtrats per paraules",
|
||||
"account_privacy": "Privacitat",
|
||||
"hide_favorites_description": "No mostrar la llista dels meus favorits (la gent seguirà sent notificada)",
|
||||
"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",
|
||||
"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",
|
||||
"post_look_feel": "Aspecte i Sensació de les Publicacions",
|
||||
"post_look_feel": "Aspecte i Sensació dels apunts",
|
||||
"mention_links": "Enllaços de mencions",
|
||||
"email_language": "Llengua per a rebre correus des d'el servidor",
|
||||
"wordfilter": "Filtre de paraules",
|
||||
|
@ -594,7 +594,7 @@
|
|||
"remove_backup": "Treure",
|
||||
"list_backups_error": "Error al recuperar la llista de copies de seguretat: {error}",
|
||||
"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}",
|
||||
"current_mascot": "La teva mascota actual",
|
||||
"account_alias_table_head": "Àlies",
|
||||
|
@ -607,11 +607,11 @@
|
|||
"move_account_target": "Compte destí (p.ex. {example})",
|
||||
"moved_account": "El compte s'ha mogut.",
|
||||
"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",
|
||||
"posts": "Publicacions",
|
||||
"posts": "Apunts",
|
||||
"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_tree": "Estil d'arbre",
|
||||
"show_scrollbars": "Mostra les barres de desplaçament de la columna lateral",
|
||||
|
@ -631,60 +631,60 @@
|
|||
"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_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"
|
||||
},
|
||||
"time": {
|
||||
"now": "ara mateix",
|
||||
"now_short": "ara mateix",
|
||||
"in_future": "in {0}",
|
||||
"in_future": "en {0}",
|
||||
"in_past": "fa {0}",
|
||||
"unit": {
|
||||
"day": "{0} dia",
|
||||
"days": "{0} dies",
|
||||
"days": "{0} dia | {0} dies",
|
||||
"day_short": "{0} dia",
|
||||
"days_short": "{0} dies",
|
||||
"days_short": "{0}d",
|
||||
"hour": "{0} hora",
|
||||
"hours": "{0} hores",
|
||||
"hours": "{0} hora | {0} hores",
|
||||
"hour_short": "{0}h",
|
||||
"hours_short": "{0}h",
|
||||
"minute": "{0} minute",
|
||||
"minutes": "{0} minutes",
|
||||
"minutes": "{0} minuts | {0} minuts",
|
||||
"minute_short": "{0}min",
|
||||
"minutes_short": "{0}min",
|
||||
"month": "{0} mes",
|
||||
"months": "{0} mesos",
|
||||
"months": "{0} mes | {0} mesos",
|
||||
"month_short": "{0} mes",
|
||||
"months_short": "{0} mesos",
|
||||
"months_short": "{0}mes",
|
||||
"second": "{0} segon",
|
||||
"seconds": "{0} segons",
|
||||
"seconds": "{0} segon | {0} segons",
|
||||
"second_short": "{0}s",
|
||||
"seconds_short": "{0}s",
|
||||
"week": "{0} setmana",
|
||||
"weeks": "{0} setmanes",
|
||||
"weeks": "{0} setmana | {0} setmanes",
|
||||
"week_short": "{0} setm.",
|
||||
"weeks_short": "{0} setm.",
|
||||
"weeks_short": "{0}setm.",
|
||||
"year": "{0} any",
|
||||
"years": "{0} anys",
|
||||
"years": "{0} any | {0} anys",
|
||||
"year_short": "{0} any",
|
||||
"years_short": "{0} anys"
|
||||
"years_short": "{0}anys"
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"collapse": "Replega",
|
||||
"conversation": "Conversa",
|
||||
"error_fetching": "S'ha produït un error en carregar les entrades",
|
||||
"load_older": "Carrega entrades anteriors",
|
||||
"no_retweet_hint": "L'entrada és només per a seguidores o és \"directa\", i per tant no es pot republicar",
|
||||
"repeated": "republicat",
|
||||
"load_older": "Carrega apunts anteriors",
|
||||
"no_retweet_hint": "L'apunt és només per a seguidors o és \"directe\" i no es pot repetir o citar",
|
||||
"repeated": "repetit",
|
||||
"show_new": "Mostra els nous",
|
||||
"up_to_date": "Actualitzat",
|
||||
"socket_reconnected": "Connexió a temps real establerta",
|
||||
"socket_broke": "Connexió a temps real perduda: codi CloseEvent {0}",
|
||||
"error": "Error de càrrega de la línia de temps: {0}",
|
||||
"no_statuses": "No hi ha entrades",
|
||||
"error": "Error carregant la línia de temps: {0}",
|
||||
"no_statuses": "No hi ha apunts",
|
||||
"reload": "Recarrega",
|
||||
"no_more_statuses": "No hi ha més entrades"
|
||||
"no_more_statuses": "No hi ha més apunts"
|
||||
},
|
||||
"user_card": {
|
||||
"approve": "Aprova",
|
||||
|
@ -692,35 +692,35 @@
|
|||
"blocked": "Bloquejat!",
|
||||
"deny": "Denega",
|
||||
"follow": "Segueix",
|
||||
"followees": "Segueixo",
|
||||
"followers": "Seguidors/es",
|
||||
"followees": "Seguint",
|
||||
"followers": "Seguidors",
|
||||
"following": "Seguint!",
|
||||
"follows_you": "Et segueix!",
|
||||
"mute": "Silencia",
|
||||
"muted": "Silenciat",
|
||||
"per_day": "per dia",
|
||||
"remote_follow": "Seguiment remot",
|
||||
"statuses": "Estats",
|
||||
"statuses": "Apunts",
|
||||
"unblock_progress": "Desbloquejant…",
|
||||
"unmute": "Deixa de silenciar",
|
||||
"follow_progress": "Sol·licitant…",
|
||||
"admin_menu": {
|
||||
"force_nsfw": "Marca totes les entrades amb \"No segur per a entorns laborals\"",
|
||||
"strip_media": "Esborra els audiovisuals de les entrades",
|
||||
"force_nsfw": "Marca tots els apunts amb \"No segur per a entorns laborals\"",
|
||||
"strip_media": "Esborra els Mèdia dels apunts",
|
||||
"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ó",
|
||||
"revoke_admin": "Revoca l'Admin",
|
||||
"activate_account": "Activa el compte",
|
||||
"deactivate_account": "Desactiva el compte",
|
||||
"revoke_moderator": "Revoca Moderació",
|
||||
"revoke_moderator": "Revoca Moderador",
|
||||
"delete_account": "Esborra el compte",
|
||||
"disable_remote_subscription": "Deshabilita seguir algú des d'una instància remota",
|
||||
"delete_user": "Esborra la usuària",
|
||||
"grant_admin": "Concedir permisos d'Administració",
|
||||
"grant_moderator": "Concedir permisos de Moderació",
|
||||
"force_unlisted": "Força que les publicacions no estiguin llistades",
|
||||
"sandbox": "Força que els missatges siguin només seguidors",
|
||||
"delete_user": "Esborra l'usuari",
|
||||
"grant_admin": "Concedir permisos d'Administrador",
|
||||
"grant_moderator": "Concedir permisos de Moderador",
|
||||
"force_unlisted": "Força que els apunts no estiguin llistats",
|
||||
"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?"
|
||||
},
|
||||
"edit_profile": "Edita el perfil",
|
||||
|
@ -747,15 +747,15 @@
|
|||
"striped": "Fons a ratlles",
|
||||
"side": "Ratlla lateral"
|
||||
},
|
||||
"media": "Media",
|
||||
"media": "Mèdia",
|
||||
"domain_muted": "Desbloqueja el domini",
|
||||
"deactivated": "Desactivat",
|
||||
"follow_cancel": "Cancel·la la sol·licitut",
|
||||
"follow_cancel": "Cancel·la la sol·licitud",
|
||||
"mute_domain": "Bloqueja el domini",
|
||||
"note": "Nota privada"
|
||||
},
|
||||
"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_does_not_exist": "Disculpes, aquest perfil no existeix."
|
||||
},
|
||||
|
@ -865,29 +865,29 @@
|
|||
}
|
||||
},
|
||||
"status": {
|
||||
"delete": "Esborra l'entrada",
|
||||
"delete_confirm": "Segur que vols esborrar aquesta entrada?",
|
||||
"delete": "Esborra l'apunt",
|
||||
"delete_confirm": "Segur que vols esborrar aquest apunt?",
|
||||
"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",
|
||||
"repeats": "Repeticions",
|
||||
"bookmark": "Marcadors",
|
||||
"status_unavailable": "Entrada no disponible",
|
||||
"bookmark": "Marcador",
|
||||
"status_unavailable": "Apunt no disponible",
|
||||
"expand": "Expandeix",
|
||||
"copy_link": "Copia l'enllaç a l'entrada",
|
||||
"hide_full_subject": "Amaga tot el tema",
|
||||
"copy_link": "Copia l'enllaç al apunt",
|
||||
"hide_full_subject": "Amaga tot l'assumpte",
|
||||
"favorites": "Favorits",
|
||||
"replies_list": "Contestacions:",
|
||||
"replies_list": "Respostes:",
|
||||
"mute_conversation": "Silencia la conversa",
|
||||
"thread_muted": "Fil silenciat",
|
||||
"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",
|
||||
"unbookmark": "Desmarca",
|
||||
"external_source": "Font externa",
|
||||
"unpin": "Deixa de destacar al perfil",
|
||||
"pinned": "Destacat",
|
||||
"reply_to": "Contesta a",
|
||||
"reply_to": "Respon a",
|
||||
"pin": "Destaca al perfil",
|
||||
"unmute_conversation": "Deixa de silenciar la conversa",
|
||||
"mentions": "Mencions",
|
||||
|
@ -919,21 +919,21 @@
|
|||
},
|
||||
"user_reporting": {
|
||||
"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}",
|
||||
"generic_error": "Hi ha hagut un error mentre s'estava processant la teva sol·licitud.",
|
||||
"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"
|
||||
},
|
||||
"tool_tip": {
|
||||
"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",
|
||||
"reply": "Respon",
|
||||
"favorite": "Favorit",
|
||||
"user_settings": "Configuració d'usuària",
|
||||
"reject_follow_request": "Rebutja la sol·licitud de seguir",
|
||||
"user_settings": "Configuració d'usuari",
|
||||
"reject_follow_request": "Rebutja la sol·licitud de seguiment",
|
||||
"bookmark": "Marcador",
|
||||
"media_upload": "Pujar multimèdia",
|
||||
"quote": "Cita"
|
||||
|
@ -967,13 +967,13 @@
|
|||
"password_reset": "Reinicia 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.",
|
||||
"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.",
|
||||
"placeholder": "El teu correu electrònic o nom d'usuària",
|
||||
"instruction": "Introdueix la teva adreça de correu electrònic o nom d'usuària. T'enviarem un enllaç per reiniciar la teva contrasenya.",
|
||||
"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'usuari",
|
||||
"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",
|
||||
"password_reset_required": "Has de reiniciar la teva contrasenya per iniciar la sessió.",
|
||||
"password_reset_disabled": "El reinici de la contrasenya està deshabilitat. Si us plau, contacta l'administració de la teva instància.",
|
||||
"check_email": "Comprova que has rebut al correu electrònic un enllaç per reiniciar la teva contrasenya."
|
||||
"password_reset_required": "Has de reiniciar la teva contrasenya per a iniciar la sessió.",
|
||||
"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 a reiniciar la teva contrasenya."
|
||||
},
|
||||
"file_type": {
|
||||
"image": "Imatge",
|
||||
|
|
102
src/i18n/en.json
102
src/i18n/en.json
|
@ -18,12 +18,12 @@
|
|||
"not_applicable": "N/A",
|
||||
"accept": "Accept",
|
||||
"accept_desc": "This instance only accepts messages from the following instances:",
|
||||
"reject": "Reject",
|
||||
"reject_desc": "This instance will not accept messages from the following instances:",
|
||||
"reject": "Instance Blocks",
|
||||
"reject_desc": "This instance blocks posts to and from the following instances:",
|
||||
"quarantine": "Quarantine",
|
||||
"quarantine_desc": "This instance will send only public posts to the following instances:",
|
||||
"ftl_removal": "Removal from \"Known Network\" Timeline",
|
||||
"ftl_removal_desc": "This instance removes these instances from \"Known Network\" timeline:",
|
||||
"quarantine_desc": "This instance will not send posts to the following instances:",
|
||||
"ftl_removal": "Removal from Federated Timeline",
|
||||
"ftl_removal_desc": "This instance removes these instances from the Federated Timeline:",
|
||||
"media_removal": "Media Removal",
|
||||
"media_removal_desc": "This instance removes media from posts on the following instances:",
|
||||
"media_nsfw": "Media force-set as sensitive",
|
||||
|
@ -106,7 +106,8 @@
|
|||
"direct": "Direct",
|
||||
"private": "Followers-only",
|
||||
"public": "Public",
|
||||
"unlisted": "Unlisted"
|
||||
"unlisted": "Unlisted",
|
||||
"local": "Local-only post -- only your instance can see this status"
|
||||
}
|
||||
},
|
||||
"image_cropper": {
|
||||
|
@ -125,7 +126,7 @@
|
|||
"description": "Log in with OAuth",
|
||||
"logout": "Log out",
|
||||
"password": "Password",
|
||||
"placeholder": "myusername",
|
||||
"placeholder": "i.e. bobvibes420",
|
||||
"register": "Register",
|
||||
"username": "Username",
|
||||
"hint": "Log in to join the discussion",
|
||||
|
@ -148,18 +149,18 @@
|
|||
"about": "About",
|
||||
"administration": "Administration",
|
||||
"back": "Back",
|
||||
"friend_requests": "Follow requests",
|
||||
"friend_requests": "Follow Requests",
|
||||
"mentions": "Mentions",
|
||||
"interactions": "Interactions",
|
||||
"dms": "Direct messages",
|
||||
"public_tl": "Public timeline",
|
||||
"dms": "Direct Messages",
|
||||
"public_tl": "Local Timeline",
|
||||
"public_timeline_description": "Public posts from this instance",
|
||||
"timeline": "Timeline",
|
||||
"home_timeline": "Home timeline",
|
||||
"home_timeline": "Home Timeline",
|
||||
"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",
|
||||
"twkn": "Known Network",
|
||||
"twkn": "Federated Timeline",
|
||||
"twkn_timeline_description": "Posts from the entire network",
|
||||
"bookmarks": "Bookmarks",
|
||||
"user_search": "User Search",
|
||||
|
@ -180,7 +181,7 @@
|
|||
"load_older": "Load older notifications",
|
||||
"notifications": "Notifications",
|
||||
"read": "Read!",
|
||||
"repeated_you": "repeated your status",
|
||||
"repeated_you": "boosted your status",
|
||||
"no_more_notifications": "No more notifications",
|
||||
"migrated_to": "migrated to",
|
||||
"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."
|
||||
},
|
||||
"interactions": {
|
||||
"favs_repeats": "Repeats and favorites",
|
||||
"favs_repeats": "Boosts and favorites",
|
||||
"follows": "New follows",
|
||||
"moves": "User migrates",
|
||||
"load_older": "Load older interactions"
|
||||
|
@ -236,8 +237,8 @@
|
|||
"text/bbcode": "BBCode",
|
||||
"text/x.misskeymarkdown": "MFM"
|
||||
},
|
||||
"content_warning": "Subject (optional)",
|
||||
"default": "Just arrived at Luna Nova Academy",
|
||||
"content_warning": "Content Warning / Subject (optional)",
|
||||
"default": "Just landed on Neptune",
|
||||
"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.",
|
||||
"posting": "Posting",
|
||||
|
@ -257,7 +258,7 @@
|
|||
"private": "Followers-only - post to followers only",
|
||||
"public": "Public - 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": {
|
||||
|
@ -369,7 +370,17 @@
|
|||
"changed_password": "Password changed successfully!",
|
||||
"chatMessageRadius": "Chat message",
|
||||
"collapse_subject": "Collapse posts with subjects",
|
||||
"columns": "Columns",
|
||||
"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",
|
||||
"current_avatar": "Your current avatar",
|
||||
"current_mascot": "Your current mascot",
|
||||
|
@ -424,6 +435,10 @@
|
|||
"hide_shoutbox": "Hide instance shoutbox",
|
||||
"right_sidebar": "Reverse order of columns",
|
||||
"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",
|
||||
"preload_images": "Preload images",
|
||||
"use_one_click_nsfw": "Open NSFW attachments with just one click",
|
||||
|
@ -479,7 +494,7 @@
|
|||
"notification_visibility_follows": "Follows",
|
||||
"notification_visibility_likes": "Favorites",
|
||||
"notification_visibility_mentions": "Mentions",
|
||||
"notification_visibility_repeats": "Repeats",
|
||||
"notification_visibility_repeats": "Boosts",
|
||||
"notification_visibility_moves": "User Migrates",
|
||||
"notification_visibility_emoji_reactions": "Reactions",
|
||||
"notification_visibility_polls": "Ends of polls you voted in",
|
||||
|
@ -540,6 +555,7 @@
|
|||
"conversation_display": "Conversation display style",
|
||||
"conversation_display_tree": "Tree-style",
|
||||
"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",
|
||||
"third_column_mode": "When there's enough space, show third column containing",
|
||||
"third_column_mode_none": "Don't show third column at all",
|
||||
|
@ -556,8 +572,10 @@
|
|||
"sensitive_by_default": "Mark posts as sensitive by default",
|
||||
"sensitive_if_subject": "Automatically mark images as sensitive if a subject line is specified",
|
||||
"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?",
|
||||
"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",
|
||||
"user_mutes": "Users",
|
||||
"useStreamingApi": "Receive posts and notifications real-time",
|
||||
|
@ -567,6 +585,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_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",
|
||||
"translation_language": "Automatic Translation Language",
|
||||
"type_domains_to_mute": "Search domains to mute",
|
||||
"upload_a_photo": "Upload a photo",
|
||||
"user_settings": "User Settings",
|
||||
|
@ -776,8 +795,8 @@
|
|||
"conversation": "Conversation",
|
||||
"error": "Error fetching timeline: {0}",
|
||||
"load_older": "Load older statuses",
|
||||
"no_retweet_hint": "Post is marked as followers-only or direct and cannot be repeated or quoted",
|
||||
"repeated": "repeated",
|
||||
"no_retweet_hint": "Post is marked as followers-only or direct and cannot be boosted or quoted",
|
||||
"repeated": "boosted",
|
||||
"show_new": "Show new",
|
||||
"reload": "Reload",
|
||||
"up_to_date": "Up-to-date",
|
||||
|
@ -788,15 +807,24 @@
|
|||
},
|
||||
"status": {
|
||||
"favorites": "Favorites",
|
||||
"repeats": "Repeats",
|
||||
"repeats": "Boosts",
|
||||
"delete": "Delete status",
|
||||
"pin": "Pin on profile",
|
||||
"unpin": "Unpin from profile",
|
||||
"pinned": "Pinned",
|
||||
"bookmark": "Bookmark",
|
||||
"unbookmark": "Unbookmark",
|
||||
"translate": "Translate",
|
||||
"translated_from": "Translated from {language}",
|
||||
"delete_confirm": "Do you really want to delete this status?",
|
||||
"reply_to": "Reply to",
|
||||
"delete_confirm_title": "Confirm deletion",
|
||||
"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",
|
||||
"replies_list": "Replies:",
|
||||
"replies_list_with_others": "Replies (+{numReplies} other): | Replies (+{numReplies} others):",
|
||||
|
@ -841,10 +869,23 @@
|
|||
},
|
||||
"user_card": {
|
||||
"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_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!",
|
||||
"deactivated": "Deactivated",
|
||||
"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",
|
||||
"favorites": "Favorites",
|
||||
"follow": "Follow",
|
||||
|
@ -862,9 +903,14 @@
|
|||
"mention": "Mention",
|
||||
"message": "Message",
|
||||
"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",
|
||||
"per_day": "per day",
|
||||
"remote_follow": "Remote follow",
|
||||
"replies": "With Replies",
|
||||
"report": "Report",
|
||||
"statuses": "Statuses",
|
||||
"subscribe": "Subscribe",
|
||||
|
@ -872,11 +918,15 @@
|
|||
"unblock": "Unblock",
|
||||
"unblock_progress": "Unblocking…",
|
||||
"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_progress": "Unmuting…",
|
||||
"mute_progress": "Muting…",
|
||||
"hide_repeats": "Hide repeats",
|
||||
"show_repeats": "Show repeats",
|
||||
"hide_repeats": "Hide boosts",
|
||||
"show_repeats": "Show boosts",
|
||||
"domain_muted": "Unblock domain",
|
||||
"mute_domain": "Block domain",
|
||||
"bot": "Bot",
|
||||
|
@ -928,7 +978,7 @@
|
|||
"tool_tip": {
|
||||
"media_upload": "Upload media",
|
||||
"quote": "Quote",
|
||||
"repeat": "Repeat",
|
||||
"repeat": "Boost",
|
||||
"reply": "Reply",
|
||||
"favorite": "Favorite",
|
||||
"add_reaction": "Add Reaction",
|
||||
|
|
|
@ -561,69 +561,39 @@
|
|||
"mention_link_display_full": "名前とドメイン、例: {'@'}foo{'@'}example.org",
|
||||
"fun": "お楽しみ",
|
||||
"virtual_scrolling": "タイムラインの描画を最適化する",
|
||||
"type_domains_to_mute": "ミュートしたいドメインを検索",
|
||||
"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": "アクセント",
|
||||
"mutes_imported": "ミュートをインポートしました!少し時間がかかるかもしれません。",
|
||||
"emoji_reactions_on_timeline": "絵文字リアクションをタイムラインに表示",
|
||||
"domain_mutes": "ドメイン",
|
||||
"mutes_and_blocks": "ミュートとブロック",
|
||||
"chatMessageRadius": "チャットメッセージ",
|
||||
"change_email_error": "メールアドレスを変えることが、できなかったかもしれません。",
|
||||
"changed_email": "メールアドレスが、変わりました!",
|
||||
"change_email": "メールアドレスを変える",
|
||||
"bot": "これは bot アカウントです",
|
||||
"mute_export_button": "ミュートをCSVファイルにエクスポートする",
|
||||
"import_mutes_from_a_csv_file": "CSVファイルからミュートをインポートする",
|
||||
"mute_import_error": "ミュートのインポートに失敗しました",
|
||||
"mute_import": "ミュートのインポート",
|
||||
"mute_export": "ミュートのエクスポート",
|
||||
"allow_following_move": "フォロー中のアカウントが引っ越したとき、自動フォローを許可する",
|
||||
"setting_changed": "規定の設定と異なっています",
|
||||
"greentext": "引用を緑色で表示",
|
||||
"sensitive_by_default": "はじめから投稿をセンシティブとして設定",
|
||||
"sensitive_if_subject": "ステータスにサブジェクトをついたらNSFWにする",
|
||||
"render_mfm": "Misskey Markdownを表示",
|
||||
"more_settings": "その他の設定",
|
||||
"reply_visibility_self_short": "自分宛のリプライを見る",
|
||||
"reply_visibility_following_short": "フォローしている人に宛てられたリプライを見る",
|
||||
"hide_all_muted_posts": "ミュートした投稿を隠す",
|
||||
"hide_media_previews": "メディアのプレビューを隠す",
|
||||
"word_filter": "単語フィルタ",
|
||||
"file_export_import": {
|
||||
"errors": {
|
||||
"invalid_file": "これはPleromaの設定をバックアップしたファイルではありません。",
|
||||
"file_slightly_new": "ファイルのマイナーバージョンが異なり、一部の設定が読み込まれないことがあります"
|
||||
},
|
||||
"restore_settings": "設定をファイルから復元する",
|
||||
"backup_settings_theme": "テーマを含む設定をファイルにバックアップする",
|
||||
"backup_settings": "設定をファイルにバックアップする",
|
||||
"backup_restore": "設定をバックアップ"
|
||||
},
|
||||
"save": "変更を保存",
|
||||
"hide_shoutbox": "Shoutboxを表示しない",
|
||||
"always_show_post_button": "投稿ボタンを常に表示",
|
||||
"right_sidebar": "サイドバーを右に表示"
|
||||
"word_filter": "単語フィルタ"
|
||||
},
|
||||
"status": {
|
||||
"bookmark": "ブックマーク",
|
||||
"copy_link": "リンクをコピー",
|
||||
"delete": "ステータスを削除",
|
||||
"delete_confirm": "本当にこのステータスを削除してもよろしいですか?",
|
||||
"expand": "広げる",
|
||||
"external_source": "外部ソース",
|
||||
"favorites": "お気に入り",
|
||||
"hide_content": "隠す",
|
||||
"hide_full_subject": "隠す",
|
||||
"mentions": "メンション",
|
||||
"mute_conversation": "スレッドをミュート",
|
||||
"nsfw": "閲覧注意",
|
||||
"pin": "プロフィールにピン留め",
|
||||
"pinned": "ピン留め",
|
||||
"plus_more": "ほか{number}件",
|
||||
"repeats": "リピート",
|
||||
"replies_list": "返信:",
|
||||
"reply_to": "返信",
|
||||
"show_content": "見る",
|
||||
"show_full_subject": "全部見る",
|
||||
"status_deleted": "この投稿は削除されました",
|
||||
"status_unavailable": "利用できません",
|
||||
"thread_muted": "ミュートされたスレッド",
|
||||
"thread_muted_and_words": "以下の単語を含むため:",
|
||||
"translate": "翻訳",
|
||||
"translated_from": "{language}から翻訳されました",
|
||||
"unbookmark": "ブックマーク解除",
|
||||
"unmute_conversation": "スレッドのミュートを解除",
|
||||
"unpin": "プロフィールのピン留めを外す",
|
||||
"you": "(あなた)"
|
||||
},
|
||||
"time": {
|
||||
"now": "たった今",
|
||||
|
|
|
@ -31,10 +31,15 @@ export const defaultState = {
|
|||
// bad name: actually hides posts of muted USERS
|
||||
hideMutedPosts: undefined, // instance default
|
||||
hideMutedThreads: undefined, // instance default
|
||||
hideThreadsWithBlockedUsers: undefined, // instance default
|
||||
hideWordFilteredPosts: undefined, // instance default
|
||||
muteBotStatuses: undefined, // instance default
|
||||
collapseMessageWithSubject: undefined, // instance default
|
||||
collapseMessageWithSubject: true, // instance default
|
||||
padEmoji: true,
|
||||
showNavShortcuts: undefined, // instance default
|
||||
showWiderShortcuts: undefined, // instance default
|
||||
hideSiteFavicon: undefined, // instance default
|
||||
hideSiteName: undefined, // instance default
|
||||
hideAttachments: false,
|
||||
hideAttachmentsInConv: false,
|
||||
maxThumbnails: 16,
|
||||
|
@ -44,11 +49,11 @@ export const defaultState = {
|
|||
loopVideoSilentOnly: true,
|
||||
streaming: false,
|
||||
emojiReactionsOnTimeline: true,
|
||||
alwaysShowNewPostButton: false,
|
||||
alwaysShowNewPostButton: true,
|
||||
autohideFloatingPostButton: false,
|
||||
pauseOnUnfocused: true,
|
||||
stopGifs: true,
|
||||
replyVisibility: 'all',
|
||||
stopGifs: false,
|
||||
replyVisibility: 'following',
|
||||
thirdColumnMode: 'notifications',
|
||||
notificationVisibility: {
|
||||
follows: true,
|
||||
|
@ -66,7 +71,7 @@ export const defaultState = {
|
|||
highlight: {},
|
||||
interfaceLanguage: browserLocale,
|
||||
hideScopeNotice: false,
|
||||
useStreamingApi: true,
|
||||
useStreamingApi: false,
|
||||
sidebarRight: undefined, // instance default
|
||||
scopeCopy: undefined, // instance default
|
||||
subjectLineBehavior: undefined, // instance default
|
||||
|
@ -75,6 +80,14 @@ export const defaultState = {
|
|||
minimalScopesMode: undefined, // instance default
|
||||
// This hides statuses filtered via a word filter
|
||||
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,
|
||||
useOneClickNsfw: false,
|
||||
useContainFit: true,
|
||||
|
@ -84,7 +97,7 @@ export const defaultState = {
|
|||
useAtIcon: undefined, // instance default
|
||||
mentionLinkDisplay: undefined, // instance default
|
||||
mentionLinkShowTooltip: undefined, // instance default
|
||||
mentionLinkShowAvatar: undefined, // instance default
|
||||
mentionLinkShowAvatar: true, // instance default
|
||||
mentionLinkFadeDomain: undefined, // instance default
|
||||
mentionLinkShowYous: undefined, // instance default
|
||||
mentionLinkBoldenYou: undefined, // instance default
|
||||
|
@ -94,12 +107,14 @@ export const defaultState = {
|
|||
virtualScrolling: undefined, // instance default
|
||||
sensitiveByDefault: undefined, // instance default
|
||||
sensitiveIfSubject: undefined,
|
||||
renderMisskeyMarkdown: undefined,
|
||||
renderMisskeyMarkdown: true,
|
||||
mfmOnHover: undefined, // instance default
|
||||
conversationDisplay: undefined, // instance default
|
||||
conversationTreeAdvanced: undefined, // instance default
|
||||
conversationOtherRepliesButton: undefined, // instance default
|
||||
conversationTreeFadeAncestors: undefined, // instance default
|
||||
maxDepthInThread: undefined // instance default
|
||||
maxDepthInThread: undefined, // instance default
|
||||
translationLanguage: undefined // instance default
|
||||
}
|
||||
|
||||
// caching the instance default properties
|
||||
|
@ -172,6 +187,7 @@ const config = {
|
|||
case 'interfaceLanguage':
|
||||
messages.setLanguage(this.getters.i18n, value)
|
||||
Cookies.set(BACKEND_LANGUAGE_COOKIE_NAME, localeService.internalToBackendLocale(value))
|
||||
dispatch('setInstanceOption', { name: 'interfaceLanguage', value })
|
||||
break
|
||||
case 'thirdColumnMode':
|
||||
dispatch('setLayoutWidth', undefined)
|
||||
|
|
|
@ -17,8 +17,8 @@ const defaultState = {
|
|||
defaultAvatar: '/images/avi.png',
|
||||
defaultBanner: '/images/banner.png',
|
||||
background: '/static/aurora_borealis.jpg',
|
||||
collapseMessageWithSubject: false,
|
||||
greentext: false,
|
||||
collapseMessageWithSubject: true,
|
||||
greentext: true,
|
||||
useAtIcon: false,
|
||||
mentionLinkDisplay: 'short',
|
||||
mentionLinkShowTooltip: true,
|
||||
|
@ -30,12 +30,22 @@ const defaultState = {
|
|||
// bad name: actually hides posts of muted USERS
|
||||
hideMutedPosts: false,
|
||||
hideMutedThreads: true,
|
||||
hideThreadsWithBlockedUsers: false,
|
||||
hideWordFilteredPosts: false,
|
||||
hidePostStats: false,
|
||||
hideBotIndication: false,
|
||||
hideSitename: false,
|
||||
hideSiteFavicon: false,
|
||||
hideSiteName: false,
|
||||
hideUserStats: false,
|
||||
muteBotStatuses: false,
|
||||
modalOnRepeat: false,
|
||||
modalOnUnfollow: false,
|
||||
modalOnBlock: true,
|
||||
modalOnMute: false,
|
||||
modalOnDelete: true,
|
||||
modalOnLogout: true,
|
||||
modalOnApproveFollow: false,
|
||||
modalOnDenyFollow: false,
|
||||
loginMethod: 'password',
|
||||
logo: '/static/logo.svg',
|
||||
logoMargin: '.2em',
|
||||
|
@ -49,13 +59,16 @@ const defaultState = {
|
|||
scopeCopy: true,
|
||||
showFeaturesPanel: true,
|
||||
showInstanceSpecificPanel: false,
|
||||
showNavShortcuts: true,
|
||||
showWiderShortcuts: false,
|
||||
sidebarRight: false,
|
||||
subjectLineBehavior: 'email',
|
||||
theme: 'pleroma-dark',
|
||||
virtualScrolling: true,
|
||||
sensitiveByDefault: false,
|
||||
sensitiveIfSubject: true,
|
||||
renderMisskeyMarkdown: false,
|
||||
renderMisskeyMarkdown: true,
|
||||
mfmOnHover: false,
|
||||
conversationDisplay: 'linear',
|
||||
conversationTreeAdvanced: false,
|
||||
conversationOtherRepliesButton: 'below',
|
||||
|
|
|
@ -64,7 +64,8 @@ export const defaultState = () => ({
|
|||
dms: emptyTl(),
|
||||
bookmarks: emptyTl(),
|
||||
list: emptyTl(),
|
||||
bubble: emptyTl()
|
||||
bubble: emptyTl(),
|
||||
replies: emptyTl()
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -183,7 +184,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
|
|||
// This makes sure that user timeline won't get data meant for other
|
||||
// user. I.e. opening different user profiles makes request which could
|
||||
// return data late after user already viewing different user profile
|
||||
if ((timeline === 'user' || timeline === 'media') && timelineObject.userId !== userId) {
|
||||
if ((timeline === 'user' || timeline === 'media' || timeline === 'replies') && timelineObject.userId !== userId) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -425,6 +426,10 @@ export const mutations = {
|
|||
state.conversationsObject[newStatus.statusnet_conversation_id].forEach(status => { status.thread_muted = newStatus.thread_muted })
|
||||
}
|
||||
},
|
||||
setTranslatedStatus (state, { id, translation }) {
|
||||
const newStatus = state.allStatusesObject[id]
|
||||
newStatus.translation = translation
|
||||
},
|
||||
setRetweeted (state, { status, value }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
|
||||
|
@ -637,6 +642,10 @@ const statuses = {
|
|||
rootState.api.backendInteractor.unpinOwnStatus({ id: statusId })
|
||||
.then((status) => dispatch('addNewStatuses', { statuses: [status] }))
|
||||
},
|
||||
translateStatus ({ rootState, commit }, { id, translation, language }) {
|
||||
return rootState.api.backendInteractor.translateStatus({ id: id, translation, language })
|
||||
.then((translation) => commit('setTranslatedStatus', { id, translation }))
|
||||
},
|
||||
muteConversation ({ rootState, commit }, statusId) {
|
||||
return rootState.api.backendInteractor.muteConversation({ id: statusId })
|
||||
.then((status) => commit('setMutedStatus', status))
|
||||
|
|
|
@ -31,6 +31,7 @@ const MASTODON_LOGIN_URL = '/api/v1/accounts/verify_credentials'
|
|||
const MASTODON_REGISTRATION_URL = '/api/v1/accounts'
|
||||
const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites'
|
||||
const MASTODON_USER_NOTIFICATIONS_URL = '/api/v1/notifications'
|
||||
const AKKOMA_TRANSLATE_URL = (id, lang) => `/api/v1/statuses/${id}/translations/${lang}`
|
||||
const MASTODON_DISMISS_NOTIFICATION_URL = id => `/api/v1/notifications/${id}/dismiss`
|
||||
const MASTODON_FAVORITE_URL = id => `/api/v1/statuses/${id}/favourite`
|
||||
const MASTODON_UNFAVORITE_URL = id => `/api/v1/statuses/${id}/unfavourite`
|
||||
|
@ -615,6 +616,7 @@ const fetchTimeline = ({
|
|||
notifications: MASTODON_USER_NOTIFICATIONS_URL,
|
||||
'publicAndExternal': MASTODON_PUBLIC_TIMELINE,
|
||||
user: MASTODON_USER_TIMELINE_URL,
|
||||
replies: MASTODON_USER_TIMELINE_URL,
|
||||
media: MASTODON_USER_TIMELINE_URL,
|
||||
list: MASTODON_LIST_TIMELINE_URL,
|
||||
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
|
||||
|
@ -626,7 +628,7 @@ const fetchTimeline = ({
|
|||
|
||||
let url = timelineUrls[timeline]
|
||||
|
||||
if (timeline === 'user' || timeline === 'media') {
|
||||
if (timeline === 'user' || timeline === 'media' || timeline === 'replies') {
|
||||
url = url(userId)
|
||||
}
|
||||
|
||||
|
@ -658,6 +660,9 @@ const fetchTimeline = ({
|
|||
if (replyVisibility !== 'all') {
|
||||
params.push(['reply_visibility', replyVisibility])
|
||||
}
|
||||
if (timeline === 'user') {
|
||||
params.push(['exclude_replies', 1])
|
||||
}
|
||||
|
||||
params.push(['limit', 20])
|
||||
|
||||
|
@ -738,6 +743,13 @@ const unretweet = ({ id, credentials }) => {
|
|||
.then((data) => parseStatus(data))
|
||||
}
|
||||
|
||||
const translateStatus = ({ id, credentials, language }) => {
|
||||
return promisedRequest({ url: AKKOMA_TRANSLATE_URL(id, language), method: 'GET', credentials })
|
||||
.then((data) => {
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
const bookmarkStatus = ({ id, credentials }) => {
|
||||
return promisedRequest({
|
||||
url: MASTODON_BOOKMARK_STATUS_URL(id),
|
||||
|
@ -1576,7 +1588,8 @@ const apiService = {
|
|||
postAnnouncement,
|
||||
editAnnouncement,
|
||||
deleteAnnouncement,
|
||||
adminFetchAnnouncements
|
||||
adminFetchAnnouncements,
|
||||
translateStatus
|
||||
}
|
||||
|
||||
export default apiService
|
||||
|
|
|
@ -49,7 +49,7 @@ const fetchAndUpdate = ({
|
|||
args['listId'] = listId
|
||||
args['tag'] = tag
|
||||
args['withMuted'] = !hideMutedPosts
|
||||
if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) {
|
||||
if (loggedIn && ['friends', 'public', 'publicAndExternal', 'bubble'].includes(timeline)) {
|
||||
args['replyVisibility'] = replyVisibility
|
||||
}
|
||||
|
||||
|
|
29
static/manifest.json
Normal file
29
static/manifest.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "☽ D̷i̵s̴q̴ordi̴a ☾",
|
||||
"short_name": "☽ D̷i̵s̴q̴ordi̴a ☾",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#000000",
|
||||
"theme_color": "#000000",
|
||||
"orientation": "portrait-primary",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/images/icons/icon-128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable any"
|
||||
},
|
||||
{
|
||||
"src": "/images/icons/icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable any"
|
||||
},
|
||||
{
|
||||
"src": "/images/icons/icon-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable any"
|
||||
}
|
||||
]
|
||||
}
|
39
static/service-worker.js
Normal file
39
static/service-worker.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Installing service worker
|
||||
const CACHE_NAME = 'Disqordia';
|
||||
|
||||
/* Add relative URL of all the static content you want to store in
|
||||
* cache storage (this will help us use our app offline)*/
|
||||
let resourcesToCache = ["/", "/static/font/css/fontello.css", "/static/font/css/animation.css", "/static/font/tiresias.css", "/static/font/css/lato.css", "/static/mfm.css", "/favicon.png", "/static/css/app.d7c75a48f7d627e0493f.css", "/static/js/vendors~app.4600ad9d6a3c807e6688.js", "/static/js/app.afaee31b8c11ba3c67aa.js"];
|
||||
|
||||
self.addEventListener("install", e=>{
|
||||
e.waitUntil(
|
||||
caches.open(CACHE_NAME).then(cache =>{
|
||||
return cache.addAll(resourcesToCache);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Cache and return requests
|
||||
self.addEventListener("fetch", e=>{
|
||||
e.respondWith(
|
||||
caches.match(e.request).then(response=>{
|
||||
return response || fetch(e.request);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Update a service worker
|
||||
const cacheWhitelist = ['Disqordia'];
|
||||
self.addEventListener('activate', event => {
|
||||
event.waitUntil(
|
||||
caches.keys().then(cacheNames => {
|
||||
return Promise.all(
|
||||
cacheNames.map(cacheName => {
|
||||
if (cacheWhitelist.indexOf(cacheName) === -1) {
|
||||
return caches.delete(cacheName);
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
Loading…
Reference in a new issue