aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEdijs <iamedijs@hotmail.com>2019-02-10 11:59:19 -0700
committerEdijs <iamedijs@hotmail.com>2019-02-10 11:59:19 -0700
commitfc26f1852ebc686ec34a7b65a3c7ad9f36ef630b (patch)
treefafab5ab9b434b4af0f70cc53dc980446b463e1c /src
parentd39e2643f523e84cdce1945538149a9bd6419fd6 (diff)
parent4bea3c525f377a45919893ae0a474859b5744820 (diff)
Merge branch 'develop' into fix/hashtag-opening
Diffstat (limited to 'src')
-rw-r--r--src/App.js3
-rw-r--r--src/App.scss14
-rw-r--r--src/App.vue7
-rw-r--r--src/boot/after_store.js3
-rw-r--r--src/components/about/about.js3
-rw-r--r--src/components/about/about.vue2
-rw-r--r--src/components/post_status_form/post_status_form.js6
-rw-r--r--src/components/post_status_form/post_status_form.vue2
-rw-r--r--src/components/public_and_external_timeline/public_and_external_timeline.js2
-rw-r--r--src/components/public_and_external_timeline/public_and_external_timeline.vue2
-rw-r--r--src/components/public_timeline/public_timeline.js2
-rw-r--r--src/components/settings/settings.js16
-rw-r--r--src/components/settings/settings.vue36
-rw-r--r--src/components/status/status.js17
-rw-r--r--src/components/status/status.vue7
-rw-r--r--src/components/tab_switcher/tab_switcher.js2
-rw-r--r--src/components/tag_timeline/tag_timeline.js4
-rw-r--r--src/components/user_card_content/user_card_content.js6
-rw-r--r--src/components/user_card_content/user_card_content.vue13
-rw-r--r--src/components/user_profile/user_profile.js16
-rw-r--r--src/components/user_profile/user_profile.vue7
-rw-r--r--src/components/user_settings/user_settings.js18
-rw-r--r--src/components/user_settings/user_settings.vue17
-rw-r--r--src/i18n/de.json4
-rw-r--r--src/i18n/en.json11
-rw-r--r--src/i18n/es.json317
-rw-r--r--src/i18n/ja.json3
-rw-r--r--src/i18n/ko.json3
-rw-r--r--src/i18n/ru.json5
-rw-r--r--src/modules/api.js19
-rw-r--r--src/modules/config.js3
-rw-r--r--src/modules/instance.js3
-rw-r--r--src/modules/users.js2
-rw-r--r--src/services/api/api.service.js10
-rw-r--r--src/services/backend_interactor_service/backend_interactor_service.js5
-rw-r--r--src/services/entity_normalizer/entity_normalizer.service.js5
36 files changed, 519 insertions, 76 deletions
diff --git a/src/App.js b/src/App.js
index 83a61d39..200254f3 100644
--- a/src/App.js
+++ b/src/App.js
@@ -81,7 +81,8 @@ export default {
},
unseenNotificationsCount () {
return this.unseenNotifications.length
- }
+ },
+ showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel }
},
methods: {
scrollToTop () {
diff --git a/src/App.scss b/src/App.scss
index d3721b32..1eaed6ea 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -719,3 +719,17 @@ nav {
margin-right: 0.8em;
}
}
+
+.login-hint {
+ text-align: center;
+
+ @media all and (min-width: 801px) {
+ display: none;
+ }
+
+ a {
+ display: inline-block;
+ padding: 1em 0px;
+ width: 100%;
+ }
+}
diff --git a/src/App.vue b/src/App.vue
index 833608ea..7541928f 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -29,7 +29,7 @@
<user-panel></user-panel>
<nav-panel></nav-panel>
<instance-specific-panel v-if="showInstanceSpecificPanel"></instance-specific-panel>
- <features-panel v-if="!currentUser"></features-panel>
+ <features-panel v-if="!currentUser && showFeaturesPanel"></features-panel>
<who-to-follow-panel v-if="currentUser && suggestionsEnabled"></who-to-follow-panel>
<notifications v-if="currentUser"></notifications>
</div>
@@ -37,6 +37,11 @@
</div>
</div>
<div class="main">
+ <div v-if="!currentUser" class="login-hint panel panel-default">
+ <router-link :to="{ name: 'login' }" class="panel-body">
+ {{ $t("login.hint") }}
+ </router-link>
+ </div>
<transition name="fade">
<router-view></router-view>
</transition>
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index 5693dcc6..fa44dace 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -59,6 +59,7 @@ const afterStoreSetup = ({ store, i18n }) => {
copyInstanceOption('background')
copyInstanceOption('hidePostStats')
copyInstanceOption('hideUserStats')
+ copyInstanceOption('hideFilteredStatuses')
copyInstanceOption('logo')
store.dispatch('setInstanceOption', {
@@ -84,8 +85,10 @@ const afterStoreSetup = ({ store, i18n }) => {
copyInstanceOption('loginMethod')
copyInstanceOption('scopeCopy')
copyInstanceOption('subjectLineBehavior')
+ copyInstanceOption('postContentType')
copyInstanceOption('alwaysShowSubjectInput')
copyInstanceOption('noAttachmentLinks')
+ copyInstanceOption('showFeaturesPanel')
if ((config.chatDisabled)) {
store.dispatch('disableChat')
diff --git a/src/components/about/about.js b/src/components/about/about.js
index b4433b4e..ae1cb182 100644
--- a/src/components/about/about.js
+++ b/src/components/about/about.js
@@ -7,6 +7,9 @@ const About = {
InstanceSpecificPanel,
FeaturesPanel,
TermsOfServicePanel
+ },
+ computed: {
+ showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel }
}
}
diff --git a/src/components/about/about.vue b/src/components/about/about.vue
index bf87e0b8..13dec87c 100644
--- a/src/components/about/about.vue
+++ b/src/components/about/about.vue
@@ -1,7 +1,7 @@
<template>
<div class="sidebar">
<instance-specific-panel></instance-specific-panel>
- <features-panel></features-panel>
+ <features-panel v-if="showFeaturesPanel"></features-panel>
<terms-of-service-panel></terms-of-service-panel>
</div>
</template>
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 5e8c2252..ab379c23 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -65,7 +65,6 @@ const PostStatusForm = {
newStatus: {
spoilerText: this.subject || '',
status: statusText,
- contentType: 'text/plain',
nsfw: false,
files: [],
visibility: scope
@@ -167,6 +166,11 @@ const PostStatusForm = {
},
formattingOptionsEnabled () {
return this.$store.state.instance.formattingOptionsEnabled
+ },
+ defaultPostContentType () {
+ return typeof this.$store.state.config.postContentType === 'undefined'
+ ? this.$store.state.instance.postContentType
+ : this.$store.state.config.postContentType
}
},
methods: {
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index e09ad37f..6ed5d92e 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -35,7 +35,7 @@
<div class="visibility-tray">
<span class="text-format" v-if="formattingOptionsEnabled">
<label for="post-content-type" class="select">
- <select id="post-content-type" v-model="newStatus.contentType" class="form-control">
+ <select id="post-content-type" v-model="defaultPostContentType" class="form-control">
<option value="text/plain">{{$t('post_status.content_type.plain_text')}}</option>
<option value="text/html">HTML</option>
<option value="text/markdown">Markdown</option>
diff --git a/src/components/public_and_external_timeline/public_and_external_timeline.js b/src/components/public_and_external_timeline/public_and_external_timeline.js
index 0db6efae..d45677e0 100644
--- a/src/components/public_and_external_timeline/public_and_external_timeline.js
+++ b/src/components/public_and_external_timeline/public_and_external_timeline.js
@@ -7,7 +7,7 @@ const PublicAndExternalTimeline = {
timeline () { return this.$store.state.statuses.timelines.publicAndExternal }
},
created () {
- this.$store.dispatch('startFetching', 'publicAndExternal')
+ this.$store.dispatch('startFetching', { timeline: 'publicAndExternal' })
},
destroyed () {
this.$store.dispatch('stopFetching', 'publicAndExternal')
diff --git a/src/components/public_and_external_timeline/public_and_external_timeline.vue b/src/components/public_and_external_timeline/public_and_external_timeline.vue
index aded2ead..6be9f955 100644
--- a/src/components/public_and_external_timeline/public_and_external_timeline.vue
+++ b/src/components/public_and_external_timeline/public_and_external_timeline.vue
@@ -1,5 +1,5 @@
<template>
- <Timeline :title="$t('nav.twkn')"v-bind:timeline="timeline" v-bind:timeline-name="'publicAndExternal'"/>
+ <Timeline :title="$t('nav.twkn')" v-bind:timeline="timeline" v-bind:timeline-name="'publicAndExternal'"/>
</template>
<script src="./public_and_external_timeline.js"></script>
diff --git a/src/components/public_timeline/public_timeline.js b/src/components/public_timeline/public_timeline.js
index 9b866be8..64c951ac 100644
--- a/src/components/public_timeline/public_timeline.js
+++ b/src/components/public_timeline/public_timeline.js
@@ -7,7 +7,7 @@ const PublicTimeline = {
timeline () { return this.$store.state.statuses.timelines.public }
},
created () {
- this.$store.dispatch('startFetching', 'public')
+ this.$store.dispatch('startFetching', { timeline: 'public' })
},
destroyed () {
this.$store.dispatch('stopFetching', 'public')
diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js
index 8d138485..534a9839 100644
--- a/src/components/settings/settings.js
+++ b/src/components/settings/settings.js
@@ -27,6 +27,11 @@ const settings = {
: user.hideUserStats,
hideUserStatsDefault: this.$t('settings.values.' + instance.hideUserStats),
+ hideFilteredStatusesLocal: typeof user.hideFilteredStatuses === 'undefined'
+ ? instance.hideFilteredStatuses
+ : user.hideFilteredStatuses,
+ hideFilteredStatusesDefault: this.$t('settings.values.' + instance.hideFilteredStatuses),
+
notificationVisibilityLocal: user.notificationVisibility,
replyVisibilityLocal: user.replyVisibility,
loopVideoLocal: user.loopVideo,
@@ -46,6 +51,11 @@ const settings = {
: user.subjectLineBehavior,
subjectLineBehaviorDefault: instance.subjectLineBehavior,
+ postContentTypeLocal: typeof user.postContentType === 'undefined'
+ ? instance.postContentType
+ : user.postContentType,
+ postContentTypeDefault: instance.postContentType,
+
alwaysShowSubjectInputLocal: typeof user.alwaysShowSubjectInput === 'undefined'
? instance.alwaysShowSubjectInput
: user.alwaysShowSubjectInput,
@@ -96,6 +106,9 @@ const settings = {
hideUserStatsLocal (value) {
this.$store.dispatch('setOption', { name: 'hideUserStats', value })
},
+ hideFilteredStatusesLocal (value) {
+ this.$store.dispatch('setOption', { name: 'hideFilteredStatuses', value })
+ },
hideNsfwLocal (value) {
this.$store.dispatch('setOption', { name: 'hideNsfw', value })
},
@@ -157,6 +170,9 @@ const settings = {
subjectLineBehaviorLocal (value) {
this.$store.dispatch('setOption', { name: 'subjectLineBehavior', value })
},
+ postContentTypeLocal (value) {
+ this.$store.dispatch('setOption', { name: 'postContentType', value })
+ },
stopGifs (value) {
this.$store.dispatch('setOption', { name: 'stopGifs', value })
},
diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue
index 9953780f..dfb2e49d 100644
--- a/src/components/settings/settings.vue
+++ b/src/components/settings/settings.vue
@@ -100,6 +100,28 @@
</label>
</div>
</li>
+ <li>
+ <div>
+ {{$t('settings.post_status_content_type')}}
+ <label for="postContentType" class="select">
+ <select id="postContentType" v-model="postContentTypeLocal">
+ <option value="text/plain">
+ {{$t('settings.status_content_type_plain')}}
+ {{postContentTypeDefault == 'text/plain' ? $t('settings.instance_default_simple') : ''}}
+ </option>
+ <option value="text/html">
+ HTML
+ {{postContentTypeDefault == 'text/html' ? $t('settings.instance_default_simple') : ''}}
+ </option>
+ <option value="text/markdown">
+ Markdown
+ {{postContentTypeDefault == 'text/markdown' ? $t('settings.instance_default_simple') : ''}}
+ </option>
+ </select>
+ <i class="icon-down-open"/>
+ </label>
+ </div>
+ </li>
</ul>
</div>
@@ -205,7 +227,6 @@
</label>
</li>
</ul>
- </label>
</div>
<div>
{{$t('settings.replies_in_timeline')}}
@@ -232,11 +253,18 @@
</div>
</div>
<div class="setting-item">
- <p>{{$t('settings.filtering_explanation')}}</p>
- <textarea id="muteWords" v-model="muteWordsString"></textarea>
+ <div>
+ <p>{{$t('settings.filtering_explanation')}}</p>
+ <textarea id="muteWords" v-model="muteWordsString"></textarea>
+ </div>
+ <div>
+ <input type="checkbox" id="hideFilteredStatuses" v-model="hideFilteredStatusesLocal">
+ <label for="hideFilteredStatuses">
+ {{$t('settings.hide_filtered_statuses')}} {{$t('settings.instance_default', { value: hideFilteredStatusesDefault })}}
+ </label>
+ </div>
</div>
</div>
-
</tab-switcher>
</keep-alive>
</div>
diff --git a/src/components/status/status.js b/src/components/status/status.js
index a3b662b6..06e4fe93 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -11,7 +11,7 @@ import generateProfileLink from 'src/services/user_profile_link_generator/user_p
import fileType from 'src/services/file_type/file_type.service'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
import { mentionMatchesUrl, extractTagFromUrl } from 'src/services/matcher/matcher.service.js'
-import { filter, find } from 'lodash'
+import { filter, find, unescape } from 'lodash'
const Status = {
name: 'Status',
@@ -110,6 +110,14 @@ const Status = {
return hits
},
muted () { return !this.unmuted && (this.status.user.muted || this.muteWordHits.length > 0) },
+ hideFilteredStatuses () {
+ return typeof this.$store.state.config.hideFilteredStatuses === 'undefined'
+ ? this.$store.state.instance.hideFilteredStatuses
+ : this.$store.state.config.hideFilteredStatuses
+ },
+ hideStatus () {
+ return (this.hideReply || this.deleted) || (this.muted && this.hideFilteredStatuses)
+ },
isFocused () {
// retweet or root of an expanded conversation
if (this.focused) {
@@ -201,14 +209,15 @@ const Status = {
},
replySubject () {
if (!this.status.summary) return ''
+ const decodedSummary = unescape(this.status.summary)
const behavior = typeof this.$store.state.config.subjectLineBehavior === 'undefined'
? this.$store.state.instance.subjectLineBehavior
: this.$store.state.config.subjectLineBehavior
- const startsWithRe = this.status.summary.match(/^re[: ]/i)
+ const startsWithRe = decodedSummary.match(/^re[: ]/i)
if (behavior !== 'noop' && startsWithRe || behavior === 'masto') {
- return this.status.summary
+ return decodedSummary
} else if (behavior === 'email') {
- return 're: '.concat(this.status.summary)
+ return 're: '.concat(decodedSummary)
} else if (behavior === 'noop') {
return ''
}
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 779696ea..76daf73a 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -1,5 +1,5 @@
<template>
- <div class="status-el" v-if="!hideReply && !deleted" :class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]">
+ <div class="status-el" v-if="!hideStatus" :class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]">
<template v-if="muted && !noReplyLinks">
<div class="media status container muted">
<small>
@@ -16,9 +16,8 @@
<UserAvatar v-if="retweet" :betterShadow="betterShadow" :src="statusoid.user.profile_image_url_original"/>
<div class="media-body faint">
<span class="user-name">
- <router-link :to="retweeterProfileLink">
- {{retweeterHtml || retweeter}}
- </router-link>
+ <router-link v-if="retweeterHtml" :to="retweeterProfileLink" v-html="retweeterHtml"/>
+ <router-link v-else :to="retweeterProfileLink">{{retweeter}}</router-link>
</span>
<i class='fa icon-retweet retweeted' :title="$t('tool_tip.repeat')"></i>
{{$t('timeline.repeated')}}
diff --git a/src/components/tab_switcher/tab_switcher.js b/src/components/tab_switcher/tab_switcher.js
index f9c3f927..423df258 100644
--- a/src/components/tab_switcher/tab_switcher.js
+++ b/src/components/tab_switcher/tab_switcher.js
@@ -37,7 +37,7 @@ export default Vue.component('tab-switcher', {
return (
<div class={ classesWrapper.join(' ')}>
- <button onClick={this.activateTab(index)} class={ classesTab.join(' ') }>{slot.data.attrs.label}</button>
+ <button disabled={slot.data.attrs.disabled} onClick={this.activateTab(index)} class={ classesTab.join(' ') }>{slot.data.attrs.label}</button>
</div>
)
})
diff --git a/src/components/tag_timeline/tag_timeline.js b/src/components/tag_timeline/tag_timeline.js
index 43de4f49..41b09706 100644
--- a/src/components/tag_timeline/tag_timeline.js
+++ b/src/components/tag_timeline/tag_timeline.js
@@ -3,7 +3,7 @@ import Timeline from '../timeline/timeline.vue'
const TagTimeline = {
created () {
this.$store.commit('clearTimeline', { timeline: 'tag' })
- this.$store.dispatch('startFetching', { 'tag': this.tag })
+ this.$store.dispatch('startFetching', { timeline: 'tag', tag: this.tag })
},
components: {
Timeline
@@ -15,7 +15,7 @@ const TagTimeline = {
watch: {
tag () {
this.$store.commit('clearTimeline', { timeline: 'tag' })
- this.$store.dispatch('startFetching', { 'tag': this.tag })
+ this.$store.dispatch('startFetching', { timeline: 'tag', tag: this.tag })
}
},
destroyed () {
diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index 6f6d04a7..1888f8c6 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -79,6 +79,12 @@ export default {
set (color) {
this.$store.dispatch('setHighlight', { user: this.user.screen_name, color })
}
+ },
+ visibleRole () {
+ const validRole = (this.user.role === 'admin' || this.user.role === 'moderator')
+ const showRole = this.isOtherUser || this.user.show_role
+
+ return validRole && showRole && this.user.role
}
},
components: {
diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index ce65ec2f..7f9909c4 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -19,7 +19,9 @@
</div>
<router-link class='user-screen-name' :to="userProfileLink(user)">
- <span class="handle">@{{user.screen_name}}</span><span v-if="user.locked"><i class="icon icon-lock"></i></span>
+ <span class="handle">@{{user.screen_name}}
+ <span class="alert staff" v-if="!hideBio && !!visibleRole">{{visibleRole}}</span>
+ </span><span v-if="user.locked"><i class="icon icon-lock"></i></span>
<span v-if="!hideUserStatsLocal && !hideBio" class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span>
</router-link>
</div>
@@ -247,6 +249,15 @@
text-overflow: ellipsis;
overflow: hidden;
}
+
+ // TODO use proper colors
+ .staff {
+ text-transform: capitalize;
+ color: $fallback--text;
+ color: var(--btnText, $fallback--text);
+ background-color: $fallback--fg;
+ background-color: var(--btn, $fallback--fg);
+ }
}
.user-meta {
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 7b0ab705..a22b8722 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -8,8 +8,8 @@ const UserProfile = {
this.$store.commit('clearTimeline', { timeline: 'user' })
this.$store.commit('clearTimeline', { timeline: 'favorites' })
this.$store.commit('clearTimeline', { timeline: 'media' })
- this.$store.dispatch('startFetching', ['user', this.fetchBy])
- this.$store.dispatch('startFetching', ['media', this.fetchBy])
+ this.$store.dispatch('startFetching', { timeline: 'user', userId: this.fetchBy })
+ this.$store.dispatch('startFetching', { timeline: 'media', userId: this.fetchBy })
this.startFetchFavorites()
if (!this.user.id) {
this.$store.dispatch('fetchUser', this.fetchBy)
@@ -58,17 +58,23 @@ const UserProfile = {
},
isExternal () {
return this.$route.name === 'external-user-profile'
+ },
+ followsTabVisible () {
+ return this.isUs || !this.user.hide_follows
+ },
+ followersTabVisible () {
+ return this.isUs || !this.user.hide_followers
}
},
methods: {
startFetchFavorites () {
if (this.isUs) {
- this.$store.dispatch('startFetching', ['favorites', this.fetchBy])
+ this.$store.dispatch('startFetching', { timeline: 'favorites', userId: this.fetchBy })
}
},
startUp () {
- this.$store.dispatch('startFetching', ['user', this.fetchBy])
- this.$store.dispatch('startFetching', ['media', this.fetchBy])
+ this.$store.dispatch('startFetching', { timeline: 'user', userId: this.fetchBy })
+ this.$store.dispatch('startFetching', { timeline: 'media', userId: this.fetchBy })
this.startFetchFavorites()
},
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 6d5b00d1..79461291 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -9,19 +9,20 @@
<tab-switcher :renderOnlyFocused="true">
<Timeline
:label="$t('user_card.statuses')"
+ :disabled="!user.statuses_count"
:embedded="true"
:title="$t('user_profile.timeline_title')"
:timeline="timeline"
:timeline-name="'user'"
:user-id="fetchBy"
/>
- <div :label="$t('user_card.followees')">
+ <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
<FollowList v-if="user.friends_count > 0" :userId="userId" :showFollowers="false" />
<div class="userlist-placeholder" v-else>
<i class="icon-spin3 animate-spin"></i>
</div>
</div>
- <div :label="$t('user_card.followers')">
+ <div :label="$t('user_card.followers')" v-if="followersTabVisible" :disabled="!user.followers_count">
<FollowList v-if="user.followers_count > 0" :userId="userId" :showFollowers="true" />
<div class="userlist-placeholder" v-else>
<i class="icon-spin3 animate-spin"></i>
@@ -29,6 +30,7 @@
</div>
<Timeline
:label="$t('user_card.media')"
+ :disabled="!media.visibleStatuses.length"
:embedded="true" :title="$t('user_card.media')"
timeline-name="media"
:timeline="media"
@@ -37,6 +39,7 @@
<Timeline
v-if="isUs"
:label="$t('user_card.favorites')"
+ :disabled="!favorites.visibleStatuses.length"
:embedded="true"
:title="$t('user_card.favorites')"
timeline-name="favorites"
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index df757dfb..d20bf308 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -12,7 +12,10 @@ const UserSettings = {
newLocked: this.$store.state.users.currentUser.locked,
newNoRichText: this.$store.state.users.currentUser.no_rich_text,
newDefaultScope: this.$store.state.users.currentUser.default_scope,
- newHideNetwork: this.$store.state.users.currentUser.hide_network,
+ hideFollows: this.$store.state.users.currentUser.hide_follows,
+ hideFollowers: this.$store.state.users.currentUser.hide_followers,
+ showRole: this.$store.state.users.currentUser.show_role,
+ role: this.$store.state.users.currentUser.role,
followList: null,
followImportError: false,
followsImported: false,
@@ -68,7 +71,10 @@ const UserSettings = {
/* eslint-disable camelcase */
const default_scope = this.newDefaultScope
const no_rich_text = this.newNoRichText
- const hide_network = this.newHideNetwork
+ const hide_follows = this.hideFollows
+ const hide_followers = this.hideFollowers
+ const show_role = this.showRole
+
/* eslint-enable camelcase */
this.$store.state.api.backendInteractor
.updateProfile({
@@ -80,7 +86,9 @@ const UserSettings = {
/* eslint-disable camelcase */
default_scope,
no_rich_text,
- hide_network
+ hide_follows,
+ hide_followers,
+ show_role
/* eslint-enable camelcase */
}}).then((user) => {
if (!user.error) {
@@ -235,7 +243,9 @@ const UserSettings = {
exportFollows () {
this.enableFollowsExport = false
this.$store.state.api.backendInteractor
- .fetchFriends({id: this.$store.state.users.currentUser.id})
+ .exportFriends({
+ id: this.$store.state.users.currentUser.id
+ })
.then((friendList) => {
this.exportPeople(friendList, 'friends.csv')
setTimeout(() => { this.enableFollowsExport = true }, 2000)
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index d0743ef0..134f70ef 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -30,8 +30,17 @@
<label for="account-no-rich-text">{{$t('settings.no_rich_text_description')}}</label>
</p>
<p>
- <input type="checkbox" v-model="newHideNetwork" id="account-hide-network">
- <label for="account-hide-network">{{$t('settings.hide_network_description')}}</label>
+ <input type="checkbox" v-model="hideFollows" id="account-hide-follows">
+ <label for="account-hide-follows">{{$t('settings.hide_follows_description')}}</label>
+ </p>
+ <p>
+ <input type="checkbox" v-model="hideFollowers" id="account-hide-followers">
+ <label for="account-hide-followers">{{$t('settings.hide_followers_description')}}</label>
+ </p>
+ <p>
+ <input type="checkbox" v-model="showRole" id="account-show-role">
+ <label for="account-show-role" v-if="role === 'admin'">{{$t('settings.show_admin_badge')}}</label>
+ <label for="account-show-role" v-if="role === 'moderator'">{{$t('settings.show_moderator_badge')}}</label>
</p>
<button :disabled='newName && newName.length === 0' class="btn btn-default" @click="updateProfile">{{$t('general.submit')}}</button>
</div>
@@ -180,5 +189,9 @@
.name-changer {
width: 100%;
}
+
+ .bg {
+ max-width: 100%;
+ }
}
</style>
diff --git a/src/i18n/de.json b/src/i18n/de.json
index c87371e6..d0bfba38 100644
--- a/src/i18n/de.json
+++ b/src/i18n/de.json
@@ -132,6 +132,7 @@
"preload_images": "Bilder vorausladen",
"hide_post_stats": "Beitragsstatistiken verbergen (z.B. die Anzahl der Favoriten)",
"hide_user_stats": "Benutzerstatistiken verbergen (z.B. die Anzahl der Follower)",
+ "hide_filtered_statuses": "Gefilterte Beiträge verbergen",
"import_followers_from_a_csv_file": "Importiere Follower, denen du folgen möchtest, aus einer CSV-Datei",
"import_theme": "Farbschema laden",
"inputRadius": "Eingabefelder",
@@ -155,7 +156,8 @@
"notification_visibility_mentions": "Erwähnungen",
"notification_visibility_repeats": "Wiederholungen",
"no_rich_text_description": "Rich-Text Formatierungen von allen Beiträgen entfernen",
- "hide_network_description": "Zeige nicht, wem ich folge und wer mir folgt",
+ "hide_follows_description": "Zeige nicht, wem ich folge",
+ "hide_followers_description": "Zeige nicht, wer mir folgt",
"nsfw_clickthrough": "Aktiviere ausblendbares Overlay für Anhänge, die als NSFW markiert sind",
"panelRadius": "Panel",
"pause_on_unfocused": "Streaming pausieren, wenn das Tab nicht fokussiert ist",
diff --git a/src/i18n/en.json b/src/i18n/en.json
index f80d8ba2..c664fbfa 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -28,7 +28,8 @@
"password": "Password",
"placeholder": "e.g. lain",
"register": "Register",
- "username": "Username"
+ "username": "Username",
+ "hint": "Log in to join the discussion"
},
"nav": {
"about": "About",
@@ -139,6 +140,7 @@
"use_one_click_nsfw": "Open NSFW attachments with just one click",
"hide_post_stats": "Hide post statistics (e.g. the number of favorites)",
"hide_user_stats": "Hide user statistics (e.g. the number of followers)",
+ "hide_filtered_statuses": "Hide filtered statuses",
"import_followers_from_a_csv_file": "Import follows from a csv file",
"import_theme": "Load preset",
"inputRadius": "Input fields",
@@ -164,7 +166,10 @@
"notification_visibility_mentions": "Mentions",
"notification_visibility_repeats": "Repeats",
"no_rich_text_description": "Strip rich text formatting from all posts",
- "hide_network_description": "Don't show who I'm following and who's following me",
+ "hide_follows_description": "Don't show who I'm following",
+ "hide_followers_description": "Don't show who's following me",
+ "show_admin_badge": "Show Admin badge in my profile",
+ "show_moderator_badge": "Show Moderator badge in my profile",
"nsfw_clickthrough": "Enable clickthrough NSFW attachment hiding",
"panelRadius": "Panels",
"pause_on_unfocused": "Pause streaming when tab is not focused",
@@ -191,6 +196,8 @@
"subject_line_email": "Like email: \"re: subject\"",
"subject_line_mastodon": "Like mastodon: copy as is",
"subject_line_noop": "Do not copy",
+ "post_status_content_type": "Post status content type",
+ "status_content_type_plain": "Plain text",
"stop_gifs": "Play-on-hover GIFs",
"streaming": "Enable automatic streaming of new posts when scrolled to the top",
"text": "Text",
diff --git a/src/i18n/es.json b/src/i18n/es.json
index 3391c6af..29c8aec4 100644
--- a/src/i18n/es.json
+++ b/src/i18n/es.json
@@ -2,99 +2,386 @@
"chat": {
"title": "Chat"
},
+ "features_panel": {
+ "chat": "Chat",
+ "gopher": "Gopher",
+ "media_proxy": "Media proxy",
+ "scope_options": "Opciones del alcance de la visibilidad",
+ "text_limit": "Límite de carácteres",
+ "title": "Características",
+ "who_to_follow": "A quién seguir"
+ },
"finder": {
"error_fetching_user": "Error al buscar usuario",
"find_user": "Encontrar usuario"
},
"general": {
"apply": "Aplicar",
- "submit": "Enviar"
+ "submit": "Enviar",
+ "more": "Más",
+ "generic_error": "Ha ocurrido un error"
},
"login": {
"login": "Identificación",
+ "description": "Identificación con OAuth",
"logout": "Salir",
"password": "Contraseña",
"placeholder": "p.ej. lain",
"register": "Registrar",
- "username": "Usuario"
+ "username": "Usuario",
+ "hint": "Inicia sesión para unirte a la discusión"
},
"nav": {
+ "about": "Sobre",
+ "back": "Volver",
"chat": "Chat Local",
+ "friend_requests": "Solicitudes de amistad",
"mentions": "Menciones",
+ "dms": "Mensajes Directo",
"public_tl": "Línea Temporal Pública",
"timeline": "Línea Temporal",
- "twkn": "Toda La Red Conocida"
+ "twkn": "Toda La Red Conocida",
+ "user_search": "Búsqueda de Usuarios",
+ "who_to_follow": "A quién seguir",
+ "preferences": "Preferencias"
},
"notifications": {
+ "broken_favorite": "Estado desconocido, buscándolo...",
+ "favorited_you": "le gusta tu estado",
"followed_you": "empezó a seguirte",
+ "load_older": "Cargar notificaciones antiguas",
"notifications": "Notificaciones",
- "read": "¡Leído!"
+ "read": "¡Leído!",
+ "repeated_you": "repite tu estado",
+ "no_more_notifications": "No hay más notificaciones"
},
"post_status": {
+ "new_status": "Publicar un nuevo estado",
+ "account_not_locked_warning": "Tu cuenta no está {0}. Cualquiera puede seguirte y leer las entradas para Solo-Seguidores.",
+ "account_not_locked_warning_link": "bloqueada",
+ "attachments_sensitive": "Contenido sensible",
+ "content_type": {
+ "plain_text": "Texto Plano"
+ },
+ "content_warning": "Tema (opcional)",
"default": "Acabo de aterrizar en L.A.",
- "posting": "Publicando"
+ "direct_warning": "Esta entrada solo será visible para los usuarios mencionados.",
+ "posting": "Publicando",
+ "scope": {
+ "direct": "Directo - Solo para los usuarios mencionados.",
+ "private": "Solo-Seguidores - Solo tus seguidores leeran la entrada",
+ "public": "Público - Entradas visibles en las Líneas Temporales Públicas",
+ "unlisted": "Sin Listar - Entradas no visibles en las Líneas Temporales Públicas"
+ }
},
"registration": {
"bio": "Biografía",
"email": "Correo electrónico",
"fullname": "Nombre a mostrar",
"password_confirm": "Confirmación de contraseña",
- "registration": "Registro"
+ "registration": "Registro",
+ "token": "Token de invitación",
+ "captcha": "CAPTCHA",
+ "new_captcha": "Click en la imagen para obtener un nuevo captca",
+ "validations": {
+ "username_required": "no puede estar vacío",
+ "fullname_required": "no puede estar vacío",
+ "email_required": "no puede estar vacío",
+ "password_required": "no puede estar vacío",
+ "password_confirmation_required": "no puede estar vacío",
+ "password_confirmation_match": "la contraseña no coincide"
+ }
},
"settings": {
+ "attachmentRadius": "Adjuntos",
"attachments": "Adjuntos",
"autoload": "Activar carga automática al llegar al final de la página",
"avatar": "Avatar",
- "background": "Segundo plano",
+ "avatarAltRadius": "Avatares (Notificaciones)",
+ "avatarRadius": "Avatares",
+ "background": "Fondo",
"bio": "Biografía",
+ "btnRadius": "Botones",
+ "cBlue": "Azul (Responder, seguir)",
+ "cGreen": "Verde (Retweet)",
+ "cOrange": "Naranja (Favorito)",
+ "cRed": "Rojo (Cancelar)",
+ "change_password": "Cambiar contraseña",
+ "change_password_error": "Hubo un problema cambiando la contraseña.",
+ "changed_password": "Contraseña cambiada correctamente!",
+ "collapse_subject": "Colapsar entradas con tema",
+ "composing": "Redactando",
+ "confirm_new_password": "Confirmar la nueva contraseña",
"current_avatar": "Tu avatar actual",
- "current_profile_banner": "Cabecera actual",
+ "current_password": "Contraseña actual",
+ "current_profile_banner": "Tu cabecera actual",
+ "data_import_export_tab": "Importar / Exportar Datos",
+ "default_vis": "Alcance de visibilidad por defecto",
+ "delete_account": "Eliminar la cuenta",
+ "delete_account_description": "Eliminar para siempre la cuenta y todos los mensajes.",
+ "delete_account_error": "Hubo un error al eliminar tu cuenta. Si el fallo persiste, ponte en contacto con el administrador de tu instancia.",
+ "delete_account_instructions": "Escribe tu contraseña para confirmar la eliminación de tu cuenta.",
+ "avatar_size_instruction": "El tamaño mínimo recomendado para el avatar es de 150X150 píxeles.",
+ "export_theme": "Exportar tema",
"filtering": "Filtros",
"filtering_explanation": "Todos los estados que contengan estas palabras serán silenciados, una por línea",
+ "follow_export": "Exportar personas que tú sigues",
+ "follow_export_button": "Exporta tus seguidores a un archivo csv",
+ "follow_export_processing": "Procesando, en breve se te preguntará para guardar el archivo",
"follow_import": "Importar personas que tú sigues",
"follow_import_error": "Error al importal el archivo",
"follows_imported": "¡Importado! Procesarlos llevará tiempo.",
"foreground": "Primer plano",
+ "general": "General",
"hide_attachments_in_convo": "Ocultar adjuntos en las conversaciones",
"hide_attachments_in_tl": "Ocultar adjuntos en la línea temporal",
- "import_followers_from_a_csv_file": "Importar personas que tú sigues apartir de un archivo csv",
- "links": "Links",
+ "hide_isp": "Ocultar el panel específico de la instancia",
+ "preload_images": "Precargar las imágenes",
+ "use_one_click_nsfw": "Abrir los adjuntos NSFW con un solo click.",
+ "hide_post_stats": "Ocultar las estadísticas de las entradas (p.ej. el número de favoritos)",
+ "hide_user_stats": "Ocultar las estadísticas del usuario (p.ej. el número de seguidores)",
+ "import_followers_from_a_csv_file": "Importar personas que tú sigues a partir de un archivo csv",
+ "import_theme": "Importar tema",
+ "inputRadius": "Campos de entrada",
+ "checkboxRadius": "Casillas de verificación",
+ "instance_default": "(por defecto: {value})",
+ "instance_default_simple": "(por defecto)",
+ "interface": "Interfaz",
+ "interfaceLanguage": "Idioma",
+ "invalid_theme_imported": "El archivo importado no es un tema válido de Pleroma. No se han realizado cambios.",
+ "limited_availability": "No disponible en tu navegador",
+ "links": "Enlaces",
+ "lock_account_description": "Restringir el acceso a tu cuenta solo a seguidores admitidos",
+ "loop_video": "Vídeos en bucle",
+ "loop_video_silent_only": "Bucle solo en vídeos sin sonido (p.ej. \"gifs\" de Mastodon)",
+ "play_videos_in_modal": "Reproducir los vídeos directamente en el visor de medios",
+ "use_contain_fit": "No recortar los adjuntos en miniaturas",
"name": "Nombre",
"name_bio": "Nombre y Biografía",
+ "new_password": "Nueva contraseña",
+ "notification_visibility": "Tipos de notificaciones a mostrar",
+ "notification_visibility_follows": "Nuevos seguidores",
+ "notification_visibility_likes": "Me gustan (Likes)",
+ "notification_visibility_mentions": "Menciones",
+ "notification_visibility_repeats": "Repeticiones (Repeats)",
+ "no_rich_text_description": "Eliminar el formato de texto enriquecido de todas las entradas",
+ "hide_follows_description": "No mostrar a quién sigo",
+ "hide_followers_description": "No mostrar quién me sigue",
+ "show_admin_badge": "Mostrar la placa de administrador en mi perfil",
+ "show_moderator_badge": "Mostrar la placa de moderador en mi perfil",
"nsfw_clickthrough": "Activar el clic para ocultar los adjuntos NSFW",
+ "panelRadius": "Paneles",
+ "pause_on_unfocused": "Parar la transmisión cuando no estés en foco.",
"presets": "Por defecto",
"profile_background": "Fondo del Perfil",
- "profile_banner": "Cabecera del perfil",
- "reply_link_preview": "Activar la previsualización del enlace de responder al pasar el ratón por encima",
+ "profile_banner": "Cabecera del Perfil",
+ "profile_tab": "Perfil",
+ "radii_help": "Estable el redondeo de las esquinas del interfaz (en píxeles)",
+ "replies_in_timeline": "Réplicas en la línea temporal",
+ "reply_link_preview": "Activar la previsualización del enlace de responder al pasar el ratón por encim",
+ "reply_visibility_all": "Mostrar todas las réplicas",
+ "reply_visibility_following": "Solo mostrar réplicas para mí o usuarios a los que sigo",
+ "reply_visibility_self": "Solo mostrar réplicas para mí",
+ "saving_err": "Error al guardar los ajustes",
+ "saving_ok": "Ajustes guardados",
+ "security_tab": "Seguridad",
+ "scope_copy": "Copiar la visibilidad cuando contestamos (En los mensajes directos (MDs) siempre se copia)",
"set_new_avatar": "Cambiar avatar",
"set_new_profile_background": "Cambiar fondo del perfil",
- "set_new_profile_banner": "Cambiar cabecera",
+ "set_new_profile_banner": "Cambiar cabecera del perfil",
"settings": "Ajustes",
+ "subject_input_always_show": "Mostrar siempre el campo del tema",
+ "subject_line_behavior": "Copiar el tema en las contestaciones",
+ "subject_line_email": "Tipo email: \"re: tema\"",
+ "subject_line_mastodon": "Tipo mastodon: copiar como es",
+ "subject_line_noop": "No copiar",
+ "post_status_content_type": "Formato de publicación",
+ "status_content_type_plain": "Texto plano",
+ "stop_gifs": "Iniciar GIFs al pasar el ratón",
"streaming": "Habilite la transmisión automática de nuevas publicaciones cuando se desplaza hacia la parte superior",
"text": "Texto",
"theme": "Tema",
"theme_help": "Use códigos de color hexadecimales (#rrggbb) para personalizar su tema de colores.",
- "user_settings": "Ajustes de Usuario"
+ "theme_help_v2_1": "También puede invalidar los colores y la opacidad de ciertos componentes si activa la casilla de verificación, use el botón \"Borrar todo\" para deshacer los cambios.",
+ "theme_help_v2_2": "Los iconos debajo de algunas entradas son indicadores de contraste de fondo/texto, desplace el ratón para obtener información detallada. Tenga en cuenta que cuando se utilizan indicadores de contraste de transparencia se muestra el peor caso posible.",
+ "tooltipRadius": "Información/alertas",
+ "user_settings": "Ajustes de Usuario",
+ "values": {
+ "false": "no",
+ "true": "sí"
+ },
+ "notifications": "Notificaciones",
+ "enable_web_push_notifications": "Habilitar las notificiaciones en el navegador",
+ "style": {
+ "switcher": {
+ "keep_color": "Mantener colores",
+ "keep_shadows": "Mantener sombras",
+ "keep_opacity": "Mantener opacidad",
+ "keep_roundness": "Mantener redondeces",
+ "keep_fonts": "Mantener fuentes",
+ "save_load_hint": "Las opciones \"Mantener\" conservan las opciones configuradas actualmente al seleccionar o cargar temas, también almacena dichas opciones al exportar un tema. Cuando se desactiven todas las casillas de verificación, el tema de exportación lo guardará todo.",
+ "reset": "Reiniciar",
+ "clear_all": "Limpiar todo",
+ "clear_opacity": "Limpiar opacidad"
+ },
+ "common": {
+ "color": "Color",
+ "opacity": "Opacidad",
+ "contrast": {
+ "hint": "El ratio de contraste es {ratio}. {level} {context}",
+ "level": {
+ "aa": "Cumple con la pauta de nivel AA (mínimo)",
+ "aaa": "Cumple con la pauta de nivel AAA (recomendado)",
+ "bad": "No cumple con las pautas de accesibilidad"
+ },
+ "context": {
+ "18pt": "para textos grandes (+18pt)",
+ "text": "para textos"
+ }
+ }
+ },
+ "common_colors": {
+ "_tab_label": "Común",
+ "main": "Colores comunes",
+ "foreground_hint": "Vea la pestaña \"Avanzado\" para un control más detallado",
+ "rgbo": "Iconos, acentos, insignias"
+ },
+ "advanced_colors": {
+ "_tab_label": "Avanzado",
+ "alert": "Fondo de Alertas",
+ "alert_error": "Error",
+ "badge": "Fondo de Insignias",
+ "badge_notification": "Notificaciones",
+ "panel_header": "Cabecera del panel",
+ "top_bar": "Barra superior",
+ "borders": "Bordes",
+ "buttons": "Botones",
+ "inputs": "Campos de entrada",
+ "faint_text": "Texto desvanecido"
+ },
+ "radii": {
+ "_tab_label": "Redondez"
+ },
+ "shadows": {
+ "_tab_label": "Sombra e iluminación",
+ "component": "Componente",
+ "override": "Sobreescribir",
+ "shadow_id": "Sombra #{value}",
+ "blur": "Difuminar",
+ "spread": "Cantidad",
+ "inset": "Insertada",
+ "hint": "Para las sombras, también puede usar --variable como un valor de color para usar las variables CSS3. Tenga en cuenta que establecer la opacidad no funcionará en este caso.",
+ "filter_hint": {
+ "always_drop_shadow": "Advertencia, esta sombra siempre usa {0} cuando el navegador lo soporta.",
+ "drop_shadow_syntax": "{0} no soporta el parámetro {1} y la palabra clave {2}.",
+ "avatar_inset": "Tenga en cuenta que la combinación de sombras insertadas como no-insertadas en los avatares, puede dar resultados inesperados con los avatares transparentes.",
+ "spread_zero": "Sombras con una cantidad > 0 aparecerá como si estuviera puesto a cero",
+ "inset_classic": "Las sombras insertadas estarán usando {0}"
+ },
+ "components": {
+ "panel": "Panel",
+ "panelHeader": "Cabecera del panel",
+ "topBar": "Barra superior",
+ "avatar": "Avatar del usuario (en la vista del perfil)",
+ "avatarStatus": "Avatar del usuario (en la vista de la entrada)",
+ "popup": "Ventanas y textos emergentes (popups & tooltips)",
+ "button": "Botones",
+ "buttonHover": "Botón (encima)",
+ "buttonPressed": "Botón (presionado)",
+ "buttonPressedHover": "Botón (presionado+encima)",
+ "input": "Campo de entrada"
+ }
+ },
+ "fonts": {
+ "_tab_label": "Fuentes",
+ "help": "Seleccione la fuente para utilizar para los elementos de la interfaz de usuario. Para \"personalizado\", debe ingresar el nombre exacto de la fuente tal como aparece en el sistema.",
+ "components": {
+ "interface": "Interfaz",
+ "input": "Campos de entrada",
+ "post": "Texto de publicaciones",
+ "postCode": "Texto monoespaciado en publicación (texto enriquecido)"
+ },
+ "family": "Nombre de la fuente",
+ "size": "Tamaño (en px)",
+ "weight": "Peso (negrita)",
+ "custom": "Personalizado"
+ },
+ "preview": {
+ "header": "Vista previa",
+ "content": "Contenido",
+ "error": "Ejemplo de error",
+ "button": "Botón",
+ "text": "Un montón de {0} y {1}",
+ "mono": "contenido",
+ "input": "Acaba de aterrizar en L.A.",
+ "faint_link": "manual útil",
+ "fine_print": "¡Lea nuestro {0} para aprender nada útil!",
+ "header_faint": "Esto está bien",
+ "checkbox": "He revisado los términos y condiciones",
+ "link": "un bonito enlace"
+ }
+ }
},
"timeline": {
+ "collapse": "Colapsar",
"conversation": "Conversación",
"error_fetching": "Error al cargar las actualizaciones",
"load_older": "Cargar actualizaciones anteriores",
+ "no_retweet_hint": "La publicación está marcada como solo para seguidores o directa y no se puede repetir",
+ "repeated": "repetida",
"show_new": "Mostrar lo nuevo",
- "up_to_date": "Actualizado"
+ "up_to_date": "Actualizado",
+ "no_more_statuses": "No hay más estados"
},
"user_card": {
+ "approve": "Aprovar",
"block": "Bloquear",
"blocked": "¡Bloqueado!",
+ "deny": "Denegar",
+ "favorites": "Favoritos",
"follow": "Seguir",
+ "follow_sent": "¡Solicitud enviada!",
+ "follow_progress": "Solicitando…",
+ "follow_again": "¿Enviar solicitud de nuevo?",
+ "follow_unfollow": "Dejar de seguir",
"followees": "Siguiendo",
"followers": "Seguidores",
"following": "¡Siguiendo!",
"follows_you": "¡Te sigue!",
+ "its_you": "¡Eres tú!",
+ "media": "Media",
"mute": "Silenciar",
"muted": "Silenciado",
"per_day": "por día",
"remote_follow": "Seguir",
"statuses": "Estados"
+ },
+ "user_profile": {
+ "timeline_title": "Linea temporal del usuario"
+ },
+ "who_to_follow": {
+ "more": "Más",
+ "who_to_follow": "A quién seguir"
+ },
+ "tool_tip": {
+ "media_upload": "Subir Medios",
+ "repeat": "Repetir",
+ "reply": "Contestar",
+ "favorite": "Favorito",
+ "user_settings": "Ajustes de usuario"
+ },
+ "upload":{
+ "error": {
+ "base": "Subida fallida.",
+ "file_too_big": "Archivo demasiado grande [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
+ "default": "Inténtalo más tarde"
+ },
+ "file_size_units": {
+ "B": "B",
+ "KiB": "KiB",
+ "MiB": "MiB",
+ "GiB": "GiB",
+ "TiB": "TiB"
+ }
}
}
diff --git a/src/i18n/ja.json b/src/i18n/ja.json
index 161856f0..afce03a4 100644
--- a/src/i18n/ja.json
+++ b/src/i18n/ja.json
@@ -157,7 +157,8 @@
"notification_visibility_mentions": "メンション",
"notification_visibility_repeats": "リピート",
"no_rich_text_description": "リッチテキストをつかわない",
- "hide_network_description": "わたしがフォローしているひとと、わたしをフォローしているひとを、みせない",
+ "hide_follows_description": "フォローしている人を表示しない",
+ "hide_followers_description": "フォローしている人を表示しない",
"nsfw_clickthrough": "NSFWなファイルをかくす",
"panelRadius": "パネル",
"pause_on_unfocused": "タブにフォーカスがないときストリーミングをとめる",
diff --git a/src/i18n/ko.json b/src/i18n/ko.json
index 4b69df07..f9e4dfa3 100644
--- a/src/i18n/ko.json
+++ b/src/i18n/ko.json
@@ -156,7 +156,8 @@
"notification_visibility_mentions": "멘션",
"notification_visibility_repeats": "반복",
"no_rich_text_description": "모든 게시물의 서식을 지우기",
- "hide_network_description": "내 팔로우와 팔로워를 숨기기",
+ "hide_follows_description": "내가 팔로우하는 사람을 표시하지 않음",
+ "hide_followers_description": "나를 따르는 사람을 보여주지 마라.",
"nsfw_clickthrough": "NSFW 이미지 \"클릭해서 보이기\"를 활성화",
"panelRadius": "패널",
"pause_on_unfocused": "탭이 활성 상태가 아닐 때 스트리밍 멈추기",
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index 0887bb59..4b0bd4b4 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -127,7 +127,10 @@
"notification_visibility_mentions": "Упоминания",
"notification_visibility_repeats": "Повторы",
"no_rich_text_description": "Убрать форматирование из всех постов",
- "hide_network_description": "Не показывать кого я читаю и кто меня читает",
+ "hide_follows_description": "Не показывать кого я читаю",
+ "hide_followers_description": "Не показывать кто читает меня",
+ "show_admin_badge": "Показывать значок администратора в моем профиле",
+ "show_moderator_badge": "Показывать значок модератора в моем профиле",
"nsfw_clickthrough": "Включить скрытие NSFW вложений",
"panelRadius": "Панели",
"pause_on_unfocused": "Приостановить загрузку когда вкладка не в фокусе",
diff --git a/src/modules/api.js b/src/modules/api.js
index 7bda13e7..31cb55c6 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -1,5 +1,4 @@
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
-import {isArray} from 'lodash'
import { Socket } from 'phoenix'
const api = {
@@ -34,20 +33,12 @@ const api = {
}
},
actions: {
- startFetching (store, timeline) {
- let userId = false
-
- // This is for user timelines
- if (isArray(timeline)) {
- userId = timeline[1]
- timeline = timeline[0]
- }
-
+ startFetching (store, {timeline = 'friends', tag = false, userId = false}) {
// Don't start fetching if we already are.
- if (!store.state.fetchers[timeline]) {
- const fetcher = store.state.backendInteractor.startFetching({timeline, store, userId})
- store.commit('addFetcher', {timeline, fetcher})
- }
+ if (store.state.fetchers[timeline]) return
+
+ const fetcher = store.state.backendInteractor.startFetching({ timeline, store, userId, tag })
+ store.commit('addFetcher', { timeline, fetcher })
},
stopFetching (store, timeline) {
const fetcher = store.state.fetchers[timeline]
diff --git a/src/modules/config.js b/src/modules/config.js
index c9528f6f..71f71376 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -30,7 +30,8 @@ const defaultState = {
interfaceLanguage: browserLocale,
scopeCopy: undefined, // instance default
subjectLineBehavior: undefined, // instance default
- alwaysShowSubjectInput: undefined // instance default
+ alwaysShowSubjectInput: undefined, // instance default
+ postContentType: undefined // instance default
}
const config = {
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 4ad41873..9bef5235 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -21,13 +21,16 @@ const defaultState = {
collapseMessageWithSubject: false,
hidePostStats: false,
hideUserStats: false,
+ hideFilteredStatuses: true,
disableChat: false,
scopeCopy: true,
subjectLineBehavior: 'email',
+ postContentType: 'text/plain',
loginMethod: 'password',
nsfwCensorImage: undefined,
vapidPublicKey: undefined,
noAttachmentLinks: false,
+ showFeaturesPanel: true,
// Nasty stuff
pleromaBackend: true,
diff --git a/src/modules/users.js b/src/modules/users.js
index ca2e0f31..4d56ec6f 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -271,7 +271,7 @@ const users = {
}
// Start getting fresh posts.
- store.dispatch('startFetching', 'friends')
+ store.dispatch('startFetching', { timeline: 'friends' })
// Get user mutes and follower info
store.rootState.api.backendInteractor.fetchMutes().then((mutedUsers) => {
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 992a6d26..92daa04e 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -130,7 +130,7 @@ const updateBanner = ({credentials, params}) => {
// description
const updateProfile = ({credentials, params}) => {
// Always include these fields, because they might be empty or false
- const fields = ['description', 'locked', 'no_rich_text', 'hide_network']
+ const fields = ['description', 'locked', 'no_rich_text', 'hide_follows', 'hide_followers', 'show_role']
let url = PROFILE_UPDATE_URL
const form = new FormData()
@@ -257,6 +257,13 @@ const fetchFriends = ({id, page, credentials}) => {
.then((data) => data.map(parseUser))
}
+const exportFriends = ({id, credentials}) => {
+ let url = `${FRIENDS_URL}?user_id=${id}&export=true`
+ return fetch(url, { headers: authHeaders(credentials) })
+ .then((data) => data.json())
+ .then((data) => data.map(parseUser))
+}
+
const fetchFollowers = ({id, page, credentials}) => {
let url = `${FOLLOWERS_URL}?user_id=${id}`
if (page) {
@@ -536,6 +543,7 @@ const apiService = {
fetchConversation,
fetchStatus,
fetchFriends,
+ exportFriends,
fetchFollowers,
followUser,
unfollowUser,
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index ed7d4b49..80c5cc5e 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -14,6 +14,10 @@ const backendInteractorService = (credentials) => {
return apiService.fetchFriends({id, page, credentials})
}
+ const exportFriends = ({id}) => {
+ return apiService.exportFriends({id, credentials})
+ }
+
const fetchFollowers = ({id, page}) => {
return apiService.fetchFollowers({id, page, credentials})
}
@@ -78,6 +82,7 @@ const backendInteractorService = (credentials) => {
fetchStatus,
fetchConversation,
fetchFriends,
+ exportFriends,
fetchFollowers,
followUser,
unfollowUser,
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index ec839673..828c48f9 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -90,6 +90,8 @@ export const parseUser = (data) => {
output.statusnet_blocking = data.statusnet_blocking
output.is_local = data.is_local
+ output.role = data.role
+ output.show_role = data.show_role
output.follows_you = data.follows_you
@@ -100,7 +102,8 @@ export const parseUser = (data) => {
output.rights = data.rights
output.no_rich_text = data.no_rich_text
output.default_scope = data.default_scope
- output.hide_network = data.hide_network
+ output.hide_follows = data.hide_follows
+ output.hide_followers = data.hide_followers
output.background_image = data.background_image
// on mastoapi this info is contained in a "relationship"
output.following = data.following