Merge remote-tracking branch 'upstream/develop' into shigusegubu
* upstream/develop: (37 commits) Match users using startsWith instead of match. Match emoji using startsWith instead of match. remove-unused-settings Preserve subject in replies. Don't use nsfw clickthrough if the post is collapsed by default. correct /static/config.json decoding save /api/statusnet/config.json connection rename apiStatusnetConfigSitePleromafe to apiConfig fix typo Add a checkbox for marking a post's attachments as NSFW When a post with a subject is collapsed, hide its attachments. Make interface language configurable from settings attachment: add support for rendering alt text on images Don't hide replies when inConversation. Fix indentation Remove old implementation of isReply. Add settings for changing the visibility of replies in the timeline. Update Russian translations update fixed error not displaying for 500 error. ...
This commit is contained in:
commit
16ec650b71
23 changed files with 392 additions and 168 deletions
|
@ -63,6 +63,7 @@
|
|||
"html-webpack-plugin": "^2.8.1",
|
||||
"http-proxy-middleware": "^0.17.2",
|
||||
"inject-loader": "^2.0.1",
|
||||
"iso-639-1": "^2.0.3",
|
||||
"isparta-loader": "^2.0.0",
|
||||
"json-loader": "^0.5.4",
|
||||
"karma": "^1.3.0",
|
||||
|
|
|
@ -20,6 +20,10 @@ export default {
|
|||
data: () => ({
|
||||
mobileActivePanel: 'timeline'
|
||||
}),
|
||||
created () {
|
||||
// Load the locale from the storage
|
||||
this.$i18n.locale = this.$store.state.config.interfaceLanguage
|
||||
},
|
||||
computed: {
|
||||
currentUser () { return this.$store.state.users.currentUser },
|
||||
background () {
|
||||
|
@ -29,7 +33,7 @@ export default {
|
|||
style () { return { 'background-image': `url(${this.background})` } },
|
||||
sitename () { return this.$store.state.config.name },
|
||||
chat () { return this.$store.state.chat.channel.state === 'joined' },
|
||||
showWhoToFollowPanel () { return this.$store.state.config.showWhoToFollowPanel },
|
||||
suggestionsEnabled () { return this.$store.state.config.suggestionsEnabled },
|
||||
showInstanceSpecificPanel () { return this.$store.state.config.showInstanceSpecificPanel }
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -63,8 +63,6 @@ button{
|
|||
box-shadow: 0px 0px 2px black;
|
||||
font-size: 14px;
|
||||
font-family: sans-serif;
|
||||
min-width: 10em;
|
||||
min-height: 2em;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0px 0px 4px rgba(255, 255, 255, 0.3);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<user-panel></user-panel>
|
||||
<nav-panel></nav-panel>
|
||||
<instance-specific-panel v-if="showInstanceSpecificPanel"></instance-specific-panel>
|
||||
<who-to-follow-panel v-if="currentUser && showWhoToFollowPanel"></who-to-follow-panel>
|
||||
<who-to-follow-panel v-if="currentUser && suggestionsEnabled"></who-to-follow-panel>
|
||||
<notifications v-if="currentUser"></notifications>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<a href="#" @click.prevent="toggleHidden()">Hide</a>
|
||||
</div>
|
||||
|
||||
<a v-if="type === 'image' && !hidden" class="image-attachment" :href="attachment.url" target="_blank">
|
||||
<a v-if="type === 'image' && !hidden" class="image-attachment" :href="attachment.url" target="_blank" :title="attachment.description">
|
||||
<StillImage :class="{'small': isSmall}" referrerpolicy="no-referrer" :mimetype="attachment.mimetype" :src="attachment.large_thumb_url || attachment.url"/>
|
||||
</a>
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<div>
|
||||
<label for="interface-language-switcher" class='select'>
|
||||
<select id="interface-language-switcher" v-model="language">
|
||||
<option v-for="(langCode, i) in languageCodes" :value="langCode">
|
||||
{{ languageNames[i] }}
|
||||
</option>
|
||||
</select>
|
||||
<i class="icon-down-open"/>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import languagesObject from '../../i18n/messages'
|
||||
import ISO6391 from 'iso-639-1'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
languageCodes () {
|
||||
return Object.keys(languagesObject)
|
||||
},
|
||||
|
||||
languageNames () {
|
||||
return _.map(this.languageCodes, ISO6391.getName)
|
||||
},
|
||||
|
||||
language: {
|
||||
get: function () { return this.$store.state.config.interfaceLanguage },
|
||||
set: function (val) {
|
||||
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
|
||||
this.$i18n.locale = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -34,6 +34,11 @@
|
|||
@import '../../_variables.scss';
|
||||
|
||||
.login-form {
|
||||
.btn {
|
||||
min-height: 28px;
|
||||
width: 10em;
|
||||
}
|
||||
|
||||
.error {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ const PostStatusForm = {
|
|||
'replyTo',
|
||||
'repliedUser',
|
||||
'attentions',
|
||||
'messageScope'
|
||||
'messageScope',
|
||||
'subject'
|
||||
],
|
||||
components: {
|
||||
MediaUpload
|
||||
|
@ -52,7 +53,9 @@ const PostStatusForm = {
|
|||
posting: false,
|
||||
highlighted: 0,
|
||||
newStatus: {
|
||||
spoilerText: this.subject,
|
||||
status: statusText,
|
||||
nsfw: false,
|
||||
files: [],
|
||||
visibility: this.messageScope || this.$store.state.users.currentUser.default_scope
|
||||
},
|
||||
|
@ -72,7 +75,7 @@ const PostStatusForm = {
|
|||
const firstchar = this.textAtCaret.charAt(0)
|
||||
if (firstchar === '@') {
|
||||
const matchedUsers = filter(this.users, (user) => (String(user.name + user.screen_name)).toUpperCase()
|
||||
.match(this.textAtCaret.slice(1).toUpperCase()))
|
||||
.startsWith(this.textAtCaret.slice(1).toUpperCase()))
|
||||
if (matchedUsers.length <= 0) {
|
||||
return false
|
||||
}
|
||||
|
@ -86,7 +89,7 @@ const PostStatusForm = {
|
|||
}))
|
||||
} else if (firstchar === ':') {
|
||||
if (this.textAtCaret === ':') { return }
|
||||
const matchedEmoji = filter(this.emoji.concat(this.customEmoji), (emoji) => emoji.shortcode.match(this.textAtCaret.slice(1)))
|
||||
const matchedEmoji = filter(this.emoji.concat(this.customEmoji), (emoji) => emoji.shortcode.startsWith(this.textAtCaret.slice(1)))
|
||||
if (matchedEmoji.length <= 0) {
|
||||
return false
|
||||
}
|
||||
|
@ -204,6 +207,7 @@ const PostStatusForm = {
|
|||
status: newStatus.status,
|
||||
spoilerText: newStatus.spoilerText || null,
|
||||
visibility: newStatus.visibility,
|
||||
sensitive: newStatus.nsfw,
|
||||
media: newStatus.files,
|
||||
store: this.$store,
|
||||
inReplyToStatusId: this.replyTo
|
||||
|
|
|
@ -75,6 +75,11 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_settings" v-if="newStatus.files.length > 0">
|
||||
<input type="checkbox" id="filesSensitive" v-model="newStatus.nsfw">
|
||||
<label for="filesSensitive" v-if="newStatus.nsfw">{{$t('post_status.attachments_sensitive')}}</label>
|
||||
<label for="filesSensitive" v-else v-html="$t('post_status.attachments_not_sensitive')"></label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -107,6 +112,10 @@
|
|||
padding: 0.5em;
|
||||
height: 32px;
|
||||
|
||||
button {
|
||||
width: 10em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.35em;
|
||||
padding: 0.35em;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-env browser */
|
||||
import StyleSwitcher from '../style_switcher/style_switcher.vue'
|
||||
import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue'
|
||||
import { filter, trim } from 'lodash'
|
||||
|
||||
const settings = {
|
||||
|
@ -8,6 +9,7 @@ const settings = {
|
|||
hideAttachmentsLocal: this.$store.state.config.hideAttachments,
|
||||
hideAttachmentsInConvLocal: this.$store.state.config.hideAttachmentsInConv,
|
||||
hideNsfwLocal: this.$store.state.config.hideNsfw,
|
||||
replyVisibilityLocal: this.$store.state.config.replyVisibility,
|
||||
loopVideoLocal: this.$store.state.config.loopVideo,
|
||||
loopVideoSilentOnlyLocal: this.$store.state.config.loopVideoSilentOnly,
|
||||
muteWordsString: this.$store.state.config.muteWords.join('\n'),
|
||||
|
@ -27,7 +29,8 @@ const settings = {
|
|||
}
|
||||
},
|
||||
components: {
|
||||
StyleSwitcher
|
||||
StyleSwitcher,
|
||||
InterfaceLanguageSwitcher
|
||||
},
|
||||
computed: {
|
||||
user () {
|
||||
|
@ -44,6 +47,9 @@ const settings = {
|
|||
hideNsfwLocal (value) {
|
||||
this.$store.dispatch('setOption', { name: 'hideNsfw', value })
|
||||
},
|
||||
replyVisibilityLocal (value) {
|
||||
this.$store.dispatch('setOption', { name: 'replyVisibility', value })
|
||||
},
|
||||
loopVideoLocal (value) {
|
||||
this.$store.dispatch('setOption', { name: 'loopVideo', value })
|
||||
},
|
||||
|
|
|
@ -38,6 +38,16 @@
|
|||
<input type="checkbox" id="hoverPreview" v-model="hoverPreviewLocal">
|
||||
<label for="hoverPreview">{{$t('settings.reply_link_preview')}}</label>
|
||||
</li>
|
||||
<li>
|
||||
<label for="replyVisibility" class="select">
|
||||
<select id="replyVisibility" v-model="replyVisibilityLocal">
|
||||
<option value="all" selected>{{$t('settings.reply_visibility_all')}}</option>
|
||||
<option value="following">{{$t('settings.reply_visibility_following')}}</option>
|
||||
<option value="self">{{$t('settings.reply_visibility_self')}}</option>
|
||||
</select>
|
||||
<i class="icon-down-open"/>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
|
@ -74,6 +84,10 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<h2>{{ $t('settings.interfaceLanguage') }}</h2>
|
||||
<interface-language-switcher />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -117,6 +131,8 @@
|
|||
|
||||
.btn {
|
||||
margin-top: 1em;
|
||||
min-height: 28px;
|
||||
width: 10em;
|
||||
}
|
||||
}
|
||||
.setting-list {
|
||||
|
|
|
@ -83,7 +83,6 @@ const Status = {
|
|||
return hits
|
||||
},
|
||||
muted () { return !this.unmuted && (this.status.user.muted || this.muteWordHits.length > 0) },
|
||||
isReply () { return !!this.status.in_reply_to_status_id },
|
||||
isFocused () {
|
||||
// retweet or root of an expanded conversation
|
||||
if (this.focused) {
|
||||
|
@ -105,6 +104,48 @@ const Status = {
|
|||
const lengthScore = this.status.statusnet_html.split(/<p|<br/).length + this.status.text.length / 80
|
||||
return lengthScore > 20
|
||||
},
|
||||
isReply () {
|
||||
if (this.status.in_reply_to_status_id) {
|
||||
return true
|
||||
}
|
||||
// For private replies where we can't see the OP, in_reply_to_status_id will be null.
|
||||
// So instead, check that the post starts with a @mention.
|
||||
if (this.status.visibility === 'private') {
|
||||
var textBody = this.status.text
|
||||
if (this.status.summary !== null) {
|
||||
textBody = textBody.substring(this.status.summary.length, textBody.length)
|
||||
}
|
||||
return textBody.startsWith('@')
|
||||
}
|
||||
return false
|
||||
},
|
||||
hideReply () {
|
||||
if (this.$store.state.config.replyVisibility === 'all') {
|
||||
return false
|
||||
}
|
||||
if (this.inlineExpanded || this.expanded || this.inConversation || !this.isReply) {
|
||||
return false
|
||||
}
|
||||
if (this.status.user.id === this.$store.state.users.currentUser.id) {
|
||||
return false
|
||||
}
|
||||
if (this.status.activity_type === 'repeat') {
|
||||
return false
|
||||
}
|
||||
var checkFollowing = this.$store.state.config.replyVisibility === 'following'
|
||||
for (var i = 0; i < this.status.attentions.length; ++i) {
|
||||
if (this.status.user.id === this.status.attentions[i].id) {
|
||||
continue
|
||||
}
|
||||
if (checkFollowing && this.status.attentions[i].following) {
|
||||
return false
|
||||
}
|
||||
if (this.status.attentions[i].id === this.$store.state.users.currentUser.id) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return this.status.attentions.length > 0
|
||||
},
|
||||
hideSubjectStatus () {
|
||||
if (this.tallStatus && !this.$store.state.config.collapseMessageWithSubject) {
|
||||
return false
|
||||
|
@ -123,6 +164,21 @@ const Status = {
|
|||
showingMore () {
|
||||
return this.showingTall || (this.status.summary && this.expandingSubject)
|
||||
},
|
||||
nsfwClickthrough () {
|
||||
if (!this.status.nsfw) {
|
||||
return false
|
||||
}
|
||||
if (this.status.summary && this.$store.state.config.collapseMessageWithSubject) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
replySubject () {
|
||||
if (this.status.summary && !this.status.summary.match(/^re[: ]/i)) {
|
||||
return 're: '.concat(this.status.summary)
|
||||
}
|
||||
return this.status.summary
|
||||
},
|
||||
attachmentSize () {
|
||||
if ((this.$store.state.config.hideAttachments && !this.inConversation) ||
|
||||
(this.$store.state.config.hideAttachmentsInConv && this.inConversation)) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="status-el" :class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]">
|
||||
<div class="status-el" v-if="!hideReply" :class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]">
|
||||
<template v-if="muted && !noReplyLinks">
|
||||
<div class="media status container muted">
|
||||
<small><router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link></small>
|
||||
|
@ -83,8 +83,8 @@
|
|||
<a v-if="showingMore" href="#" class="status-unhider" @click.prevent="toggleShowMore">Show less</a>
|
||||
</div>
|
||||
|
||||
<div v-if='status.attachments' class='attachments media-body'>
|
||||
<attachment :size="attachmentSize" :status-id="status.id" :nsfw="status.nsfw" :attachment="attachment" v-for="attachment in status.attachments" :key="attachment.id">
|
||||
<div v-if='status.attachments && !hideSubjectStatus' class='attachments media-body'>
|
||||
<attachment :size="attachmentSize" :status-id="status.id" :nsfw="nsfwClickthrough" :attachment="attachment" v-for="attachment in status.attachments" :key="attachment.id">
|
||||
</attachment>
|
||||
</div>
|
||||
|
||||
|
@ -102,7 +102,7 @@
|
|||
</div>
|
||||
<div class="container" v-if="replying">
|
||||
<div class="reply-left"/>
|
||||
<post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" :message-scope="status.visibility" v-on:posted="toggleReplying"/>
|
||||
<post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" :message-scope="status.visibility" :subject="replySubject" v-on:posted="toggleReplying"/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
|
|
@ -105,8 +105,8 @@
|
|||
<span>{{user.followers_count}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="!hideBio && user.description_html" v-html="user.description_html"></p>
|
||||
<p v-else-if="!hideBio">{{ user.description }}</p>
|
||||
<p v-if="!hideBio && user.description_html" class="profile-bio" v-html="user.description_html"></p>
|
||||
<p v-else-if="!hideBio" class="profile-bio">{{ user.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -130,7 +130,11 @@
|
|||
.profile-panel-body {
|
||||
word-wrap: break-word;
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), $fallback--bg 80%);
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--bg, $fallback--bg) 80%)
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--bg, $fallback--bg) 80%);
|
||||
|
||||
.profile-bio {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.user-info {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
function showWhoToFollow (panel, reply, aHost, aUser) {
|
||||
var users = reply.ids
|
||||
import apiService from '../../services/api/api.service.js'
|
||||
|
||||
function showWhoToFollow (panel, reply) {
|
||||
var users = reply
|
||||
var cn
|
||||
var index = 0
|
||||
var random = Math.floor(Math.random() * 10)
|
||||
|
@ -7,12 +9,12 @@ function showWhoToFollow (panel, reply, aHost, aUser) {
|
|||
var user
|
||||
user = users[cn]
|
||||
var img
|
||||
if (user.icon) {
|
||||
img = user.icon
|
||||
if (user.avatar) {
|
||||
img = user.avatar
|
||||
} else {
|
||||
img = '/images/avi.png'
|
||||
}
|
||||
var name = user.to_id
|
||||
var name = user.acct
|
||||
if (index === 0) {
|
||||
panel.img1 = img
|
||||
panel.name1 = name
|
||||
|
@ -52,27 +54,15 @@ function showWhoToFollow (panel, reply, aHost, aUser) {
|
|||
}
|
||||
|
||||
function getWhoToFollow (panel) {
|
||||
var user = panel.$store.state.users.currentUser.screen_name
|
||||
if (user) {
|
||||
var credentials = panel.$store.state.users.currentUser.credentials
|
||||
if (credentials) {
|
||||
panel.name1 = 'Loading...'
|
||||
panel.name2 = 'Loading...'
|
||||
panel.name3 = 'Loading...'
|
||||
var host = window.location.hostname
|
||||
var whoToFollowProvider = panel.$store.state.config.whoToFollowProvider
|
||||
var url
|
||||
url = whoToFollowProvider.replace(/{{host}}/g, encodeURIComponent(host))
|
||||
url = url.replace(/{{user}}/g, encodeURIComponent(user))
|
||||
window.fetch(url, {mode: 'cors'}).then(function (response) {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
} else {
|
||||
panel.name1 = ''
|
||||
panel.name2 = ''
|
||||
panel.name3 = ''
|
||||
}
|
||||
}).then(function (reply) {
|
||||
showWhoToFollow(panel, reply, host, user)
|
||||
})
|
||||
apiService.suggestions({credentials: credentials})
|
||||
.then((reply) => {
|
||||
showWhoToFollow(panel, reply)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,26 +85,26 @@ const WhoToFollowPanel = {
|
|||
moreUrl: function () {
|
||||
var host = window.location.hostname
|
||||
var user = this.user
|
||||
var whoToFollowLink = this.$store.state.config.whoToFollowLink
|
||||
var suggestionsWeb = this.$store.state.config.suggestionsWeb
|
||||
var url
|
||||
url = whoToFollowLink.replace(/{{host}}/g, encodeURIComponent(host))
|
||||
url = suggestionsWeb.replace(/{{host}}/g, encodeURIComponent(host))
|
||||
url = url.replace(/{{user}}/g, encodeURIComponent(user))
|
||||
return url
|
||||
},
|
||||
showWhoToFollowPanel () {
|
||||
return this.$store.state.config.showWhoToFollowPanel
|
||||
suggestionsEnabled () {
|
||||
return this.$store.state.config.suggestionsEnabled
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
user: function (user, oldUser) {
|
||||
if (this.showWhoToFollowPanel) {
|
||||
if (this.suggestionsEnabled) {
|
||||
getWhoToFollow(this)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted:
|
||||
function () {
|
||||
if (this.showWhoToFollowPanel) {
|
||||
if (this.suggestionsEnabled) {
|
||||
getWhoToFollow(this)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class="panel panel-default base01-background">
|
||||
<div class="panel-heading timeline-heading base02-background base04">
|
||||
<div class="title">
|
||||
Who to follow
|
||||
{{$t('who_to_follow.who_to_follow')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body who-to-follow">
|
||||
|
@ -11,7 +11,7 @@
|
|||
<img v-bind:src="img1"/> <router-link :to="{ name: 'user-profile', params: { id: id1 } }">{{ name1 }}</router-link><br>
|
||||
<img v-bind:src="img2"/> <router-link :to="{ name: 'user-profile', params: { id: id2 } }">{{ name2 }}</router-link><br>
|
||||
<img v-bind:src="img3"/> <router-link :to="{ name: 'user-profile', params: { id: id3 } }">{{ name3 }}</router-link><br>
|
||||
<img v-bind:src="$store.state.config.logo"> <a v-bind:href="moreUrl" target="_blank">More</a>
|
||||
<img v-bind:src="$store.state.config.logo"> <a v-bind:href="moreUrl" target="_blank">{{$t('who_to_follow.more')}}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -325,6 +325,9 @@ const en = {
|
|||
loop_video: 'Loop videos',
|
||||
loop_video_silent_only: 'Loop only videos without sound (i.e. Mastodon\'s "gifs")',
|
||||
reply_link_preview: 'Enable reply-link preview on mouse hover',
|
||||
reply_visibility_all: 'Show all replies',
|
||||
reply_visibility_following: 'Only show replies directed at me or users I\'m following',
|
||||
reply_visibility_self: 'Only show replies directed at me',
|
||||
follow_import: 'Follow import',
|
||||
import_followers_from_a_csv_file: 'Import follows from a csv file',
|
||||
follows_imported: 'Follows imported! Processing them will take a while.',
|
||||
|
@ -347,7 +350,8 @@ const en = {
|
|||
default_vis: 'Default visibility scope',
|
||||
profile_tab: 'Profile',
|
||||
security_tab: 'Security',
|
||||
data_import_export_tab: 'Data Import / Export'
|
||||
data_import_export_tab: 'Data Import / Export',
|
||||
interfaceLanguage: 'Interface language'
|
||||
},
|
||||
notifications: {
|
||||
notifications: 'Notifications',
|
||||
|
@ -381,6 +385,8 @@ const en = {
|
|||
account_not_locked_warning: 'Your account is not {0}. Anyone can follow you to view your follower-only posts.',
|
||||
account_not_locked_warning_link: 'locked',
|
||||
direct_warning: 'This post will only be visible to all the mentioned users.',
|
||||
attachments_sensitive: 'Attachments marked sensitive',
|
||||
attachments_not_sensitive: 'Attachments <strong>not</strong> marked sensitive',
|
||||
scope: {
|
||||
public: 'Public - Post to public timelines',
|
||||
unlisted: 'Unlisted - Do not post to public timelines',
|
||||
|
@ -398,6 +404,10 @@ const en = {
|
|||
},
|
||||
user_profile: {
|
||||
timeline_title: 'User Timeline'
|
||||
},
|
||||
who_to_follow: {
|
||||
who_to_follow: 'Who to follow',
|
||||
more: 'More'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -781,115 +791,147 @@ const ja = {
|
|||
chat: 'ローカルチャット',
|
||||
timeline: 'タイムライン',
|
||||
mentions: 'メンション',
|
||||
public_tl: '公開タイムライン',
|
||||
twkn: '接続しているすべてのネットワーク'
|
||||
public_tl: 'パブリックタイムライン',
|
||||
twkn: 'つながっているすべてのネットワーク',
|
||||
friend_requests: 'Follow Requests'
|
||||
},
|
||||
user_card: {
|
||||
follows_you: 'フォローされました!',
|
||||
following: 'フォロー中!',
|
||||
following: 'フォローしています!',
|
||||
follow: 'フォロー',
|
||||
blocked: 'ブロック済み!',
|
||||
blocked: 'ブロックしています!',
|
||||
block: 'ブロック',
|
||||
statuses: '投稿',
|
||||
statuses: 'ステータス',
|
||||
mute: 'ミュート',
|
||||
muted: 'ミュート済み',
|
||||
muted: 'ミュートしています!',
|
||||
followers: 'フォロワー',
|
||||
followees: 'フォロー',
|
||||
per_day: '/日',
|
||||
remote_follow: 'リモートフォロー'
|
||||
remote_follow: 'リモートフォロー',
|
||||
approve: 'Approve',
|
||||
deny: 'Deny'
|
||||
},
|
||||
timeline: {
|
||||
show_new: '更新',
|
||||
error_fetching: '更新の取得中にエラーが発生しました。',
|
||||
up_to_date: '最新',
|
||||
load_older: '古い投稿を読み込む',
|
||||
conversation: '会話',
|
||||
collapse: '折り畳む',
|
||||
show_new: 'よみこみ',
|
||||
error_fetching: 'よみこみがエラーになりました。',
|
||||
up_to_date: 'さいしん',
|
||||
load_older: 'ふるいステータス',
|
||||
conversation: 'スレッド',
|
||||
collapse: 'たたむ',
|
||||
repeated: 'リピート'
|
||||
},
|
||||
settings: {
|
||||
user_settings: 'ユーザー設定',
|
||||
name_bio: '名前とプロフィール',
|
||||
name: '名前',
|
||||
user_settings: 'ユーザーせってい',
|
||||
name_bio: 'なまえとプロフィール',
|
||||
name: 'なまえ',
|
||||
bio: 'プロフィール',
|
||||
avatar: 'アバター',
|
||||
current_avatar: 'あなたの現在のアバター',
|
||||
set_new_avatar: '新しいアバターを設定する',
|
||||
current_avatar: 'いまのアバター',
|
||||
set_new_avatar: 'あたらしいアバターをせっていする',
|
||||
profile_banner: 'プロフィールバナー',
|
||||
current_profile_banner: '現在のプロフィールバナー',
|
||||
set_new_profile_banner: '新しいプロフィールバナーを設定する',
|
||||
profile_background: 'プロフィールの背景',
|
||||
set_new_profile_background: '新しいプロフィールの背景を設定する',
|
||||
settings: '設定',
|
||||
current_profile_banner: 'いまのプロフィールバナー',
|
||||
set_new_profile_banner: 'あたらしいプロフィールバナーを設定する',
|
||||
profile_background: 'プロフィールのバックグラウンド',
|
||||
set_new_profile_background: 'あたらしいプロフィールのバックグラウンドをせっていする',
|
||||
settings: 'せってい',
|
||||
theme: 'テーマ',
|
||||
presets: 'プリセット',
|
||||
theme_help: '16進数カラーコード (#aabbcc) を使用してカラーテーマをカスタマイズ出来ます。',
|
||||
radii_help: 'インターフェースの縁の丸さを設定する。',
|
||||
background: '背景',
|
||||
foreground: '前景',
|
||||
text: '文字',
|
||||
theme_help: 'カラーテーマをカスタマイズできます。',
|
||||
radii_help: 'インターフェースのまるさをせっていする。',
|
||||
background: 'バックグラウンド',
|
||||
foreground: 'フォアグラウンド',
|
||||
text: 'もじ',
|
||||
links: 'リンク',
|
||||
cBlue: '青 (返信, フォロー)',
|
||||
cRed: '赤 (キャンセル)',
|
||||
cOrange: 'オレンジ (お気に入り)',
|
||||
cGreen: '緑 (リツイート)',
|
||||
cBlue: 'あお (リプライ, フォロー)',
|
||||
cRed: 'あか (キャンセル)',
|
||||
cOrange: 'オレンジ (おきにいり)',
|
||||
cGreen: 'みどり (リピート)',
|
||||
btnRadius: 'ボタン',
|
||||
inputRadius: 'Input fields',
|
||||
panelRadius: 'パネル',
|
||||
avatarRadius: 'アバター',
|
||||
avatarAltRadius: 'アバター (通知)',
|
||||
avatarAltRadius: 'アバター (つうち)',
|
||||
tooltipRadius: 'ツールチップ/アラート',
|
||||
attachmentRadius: 'ファイル',
|
||||
filtering: 'フィルタリング',
|
||||
filtering_explanation: 'これらの単語を含むすべてのものがミュートされます。1行に1つの単語を入力してください。',
|
||||
filtering_explanation: 'これらのことばをふくむすべてのものがミュートされます。1行に1つのことばをかいてください。',
|
||||
attachments: 'ファイル',
|
||||
hide_attachments_in_tl: 'タイムラインのファイルを隠す。',
|
||||
hide_attachments_in_convo: '会話の中のファイルを隠す。',
|
||||
nsfw_clickthrough: 'NSFWファイルの非表示を有効にする。',
|
||||
stop_gifs: 'カーソルを重ねた時にGIFを再生する。',
|
||||
autoload: '下にスクロールした時に自動で読み込むようにする。',
|
||||
streaming: '上までスクロールした時に自動でストリーミングされるようにする。',
|
||||
reply_link_preview: 'マウスカーソルを重ねた時に返信のプレビューを表示するようにする。',
|
||||
hide_attachments_in_tl: 'タイムラインのファイルをかくす。',
|
||||
hide_attachments_in_convo: 'スレッドのファイルをかくす。',
|
||||
nsfw_clickthrough: 'NSFWなファイルをかくす。',
|
||||
stop_gifs: 'カーソルをかさねたとき、GIFをうごかす。',
|
||||
autoload: 'したにスクロールしたとき、じどうてきによみこむ。',
|
||||
streaming: 'うえまでスクロールしたとき、じどうてきにストリーミングする。',
|
||||
reply_link_preview: 'カーソルをかさねたとき、リプライのプレビューをみる。',
|
||||
follow_import: 'フォローインポート',
|
||||
import_followers_from_a_csv_file: 'CSVファイルからフォローをインポートする。',
|
||||
follows_imported: 'フォローがインポートされました!処理に少し時間がかかるかもしれません。',
|
||||
follow_import_error: 'フォロワーのインポート中にエラーが発生しました。'
|
||||
follows_imported: 'フォローがインポートされました! すこしじかんがかかるかもしれません。',
|
||||
follow_import_error: 'フォローのインポートがエラーになりました。',
|
||||
delete_account: 'アカウントをけす',
|
||||
delete_account_description: 'あなたのアカウントとメッセージが、きえます。',
|
||||
delete_account_instructions: 'ほんとうにアカウントをけしてもいいなら、パスワードをかいてください。',
|
||||
delete_account_error: 'アカウントをけすことが、できなかったかもしれません。インスタンスのかんりしゃに、れんらくしてください。',
|
||||
follow_export: 'フォローのエクスポート',
|
||||
follow_export_processing: 'おまちください。まもなくファイルをダウンロードできます。',
|
||||
follow_export_button: 'エクスポート',
|
||||
change_password: 'パスワードをかえる',
|
||||
current_password: 'いまのパスワード',
|
||||
new_password: 'あたらしいパスワード',
|
||||
confirm_new_password: 'あたらしいパスワードのかくにん',
|
||||
changed_password: 'パスワードが、かわりました!',
|
||||
change_password_error: 'パスワードをかえることが、できなかったかもしれません。',
|
||||
lock_account_description: 'あなたがみとめたひとだけ、あなたのアカウントをフォローできます。'
|
||||
},
|
||||
notifications: {
|
||||
notifications: '通知',
|
||||
read: '読んだ!',
|
||||
notifications: 'つうち',
|
||||
read: 'よんだ!',
|
||||
followed_you: 'フォローされました',
|
||||
favorited_you: 'あなたの投稿がお気に入りされました',
|
||||
repeated_you: 'あなたの投稿がリピートされました'
|
||||
favorited_you: 'あなたのステータスがおきにいりされました',
|
||||
repeated_you: 'あなたのステータスがリピートされました'
|
||||
},
|
||||
login: {
|
||||
login: 'ログイン',
|
||||
username: 'ユーザー名',
|
||||
placeholder: '例えば lain',
|
||||
username: 'ユーザーめい',
|
||||
placeholder: 'れい: lain',
|
||||
password: 'パスワード',
|
||||
register: '登録',
|
||||
register: 'はじめる',
|
||||
logout: 'ログアウト'
|
||||
},
|
||||
registration: {
|
||||
registration: '登録',
|
||||
fullname: '表示名',
|
||||
registration: 'はじめる',
|
||||
fullname: 'スクリーンネーム',
|
||||
email: 'Eメール',
|
||||
bio: 'プロフィール',
|
||||
password_confirm: 'パスワードの確認'
|
||||
password_confirm: 'パスワードのかくにん'
|
||||
},
|
||||
post_status: {
|
||||
posting: '投稿',
|
||||
default: 'ちょうどL.A.に着陸しました。'
|
||||
posting: 'とうこう',
|
||||
content_warning: 'せつめい (かかなくてもよい)',
|
||||
default: 'はねだくうこうに、つきました。',
|
||||
account_not_locked_warning: 'あなたのアカウントは {0} ではありません。あなたをフォローすれば、だれでも、フォロワーげんていのステータスをよむことができます。',
|
||||
account_not_locked_warning_link: 'ロックされたアカウント',
|
||||
direct_warning: 'このステータスは、メンションされたユーザーだけが、よむことができます。',
|
||||
scope: {
|
||||
public: 'パブリック - パブリックタイムラインにとどきます。',
|
||||
unlisted: 'アンリステッド - パブリックタイムラインにとどきません。',
|
||||
private: 'フォロワーげんてい - フォロワーのみにとどきます。',
|
||||
direct: 'ダイレクト - メンションされたユーザーのみにとどきます。'
|
||||
}
|
||||
},
|
||||
finder: {
|
||||
find_user: 'ユーザー検索',
|
||||
error_fetching_user: 'ユーザー検索でエラーが発生しました'
|
||||
find_user: 'ユーザーをさがす',
|
||||
error_fetching_user: 'ユーザーけんさくがエラーになりました。'
|
||||
},
|
||||
general: {
|
||||
submit: '送信',
|
||||
apply: '適用'
|
||||
submit: 'そうしん',
|
||||
apply: 'てきよう'
|
||||
},
|
||||
user_profile: {
|
||||
timeline_title: 'ユーザータイムライン'
|
||||
},
|
||||
who_to_follow: {
|
||||
who_to_follow: 'おすすめユーザー',
|
||||
more: 'くわしく'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1595,6 +1637,8 @@ const ru = {
|
|||
set_new_profile_background: 'Загрузить новый фон профиля',
|
||||
settings: 'Настройки',
|
||||
theme: 'Тема',
|
||||
export_theme: 'Экспортировать текущую тему',
|
||||
import_theme: 'Загрузить сохранённую тему',
|
||||
presets: 'Пресеты',
|
||||
theme_help: 'Используйте шестнадцатеричные коды цветов (#rrggbb) для настройки темы.',
|
||||
radii_help: 'Округление краёв элементов интерфейса (в пикселях)',
|
||||
|
@ -1643,7 +1687,13 @@ const ru = {
|
|||
confirm_new_password: 'Подтверждение нового пароля',
|
||||
changed_password: 'Пароль изменён успешно.',
|
||||
change_password_error: 'Произошла ошибка при попытке изменить пароль.',
|
||||
limited_availability: 'Не доступно в вашем браузере'
|
||||
lock_account_description: 'Аккаунт доступен только подтверждённым подписчикам',
|
||||
limited_availability: 'Не доступно в вашем браузере',
|
||||
profile_tab: 'Профиль',
|
||||
security_tab: 'Безопасность',
|
||||
data_import_export_tab: 'Импорт / Экспорт данных',
|
||||
collapse_subject: 'Сворачивать посты с темой',
|
||||
interfaceLanguage: 'Язык интерфейса'
|
||||
},
|
||||
notifications: {
|
||||
notifications: 'Уведомления',
|
||||
|
|
133
src/main.js
133
src/main.js
|
@ -49,6 +49,7 @@ const persistedStateOptions = {
|
|||
'config.hideAttachments',
|
||||
'config.hideAttachmentsInConv',
|
||||
'config.hideNsfw',
|
||||
'config.replyVisibility',
|
||||
'config.autoLoad',
|
||||
'config.hoverPreview',
|
||||
'config.streaming',
|
||||
|
@ -59,6 +60,7 @@ const persistedStateOptions = {
|
|||
'config.loopVideoSilentOnly',
|
||||
'config.pauseOnUnfocused',
|
||||
'config.stopGifs',
|
||||
'config.interfaceLanguage',
|
||||
'users.lastLoginName',
|
||||
'statuses.notifications.maxSavedId'
|
||||
]
|
||||
|
@ -78,6 +80,7 @@ const store = new Vuex.Store({
|
|||
})
|
||||
|
||||
const i18n = new VueI18n({
|
||||
// By default, use the browser locale, we will update it if neccessary
|
||||
locale: currentLocale,
|
||||
fallbackLocale: 'en',
|
||||
messages
|
||||
|
@ -92,65 +95,79 @@ window.fetch('/api/statusnet/config.json')
|
|||
store.dispatch('setOption', { name: 'registrationOpen', value: (registrationClosed === '0') })
|
||||
store.dispatch('setOption', { name: 'textlimit', value: parseInt(textlimit) })
|
||||
store.dispatch('setOption', { name: 'server', value: server })
|
||||
})
|
||||
|
||||
window.fetch('/static/config.json')
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
const {theme, background, logo, showWhoToFollowPanel, whoToFollowProvider, whoToFollowLink, showInstanceSpecificPanel, scopeOptionsEnabled, collapseMessageWithSubject} = data
|
||||
store.dispatch('setOption', { name: 'theme', value: theme })
|
||||
store.dispatch('setOption', { name: 'background', value: background })
|
||||
store.dispatch('setOption', { name: 'logo', value: logo })
|
||||
store.dispatch('setOption', { name: 'showWhoToFollowPanel', value: showWhoToFollowPanel })
|
||||
store.dispatch('setOption', { name: 'whoToFollowProvider', value: whoToFollowProvider })
|
||||
store.dispatch('setOption', { name: 'whoToFollowLink', value: whoToFollowLink })
|
||||
store.dispatch('setOption', { name: 'showInstanceSpecificPanel', value: showInstanceSpecificPanel })
|
||||
store.dispatch('setOption', { name: 'scopeOptionsEnabled', value: scopeOptionsEnabled })
|
||||
store.dispatch('setOption', { name: 'collapseMessageWithSubject', value: collapseMessageWithSubject })
|
||||
if (data['chatDisabled']) {
|
||||
store.dispatch('disableChat')
|
||||
}
|
||||
var apiConfig = data.site.pleromafe
|
||||
|
||||
const routes = [
|
||||
{ name: 'root',
|
||||
path: '/',
|
||||
redirect: to => {
|
||||
var redirectRootLogin = data['redirectRootLogin']
|
||||
var redirectRootNoLogin = data['redirectRootNoLogin']
|
||||
return (store.state.users.currentUser ? redirectRootLogin : redirectRootNoLogin) || '/main/all'
|
||||
}},
|
||||
{ path: '/main/all', component: PublicAndExternalTimeline },
|
||||
{ path: '/main/public', component: PublicTimeline },
|
||||
{ path: '/main/friends', component: FriendsTimeline },
|
||||
{ path: '/tag/:tag', component: TagTimeline },
|
||||
{ name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } },
|
||||
{ name: 'user-profile', path: '/users/:id', component: UserProfile },
|
||||
{ name: 'mentions', path: '/:username/mentions', component: Mentions },
|
||||
{ name: 'settings', path: '/settings', component: Settings },
|
||||
{ name: 'registration', path: '/registration', component: Registration },
|
||||
{ name: 'registration', path: '/registration/:token', component: Registration },
|
||||
{ name: 'friend-requests', path: '/friend-requests', component: FollowRequests },
|
||||
{ name: 'user-settings', path: '/user-settings', component: UserSettings }
|
||||
]
|
||||
window.fetch('/static/config.json')
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
var staticConfig = data
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
routes,
|
||||
scrollBehavior: (to, from, savedPosition) => {
|
||||
if (to.matched.some(m => m.meta.dontScroll)) {
|
||||
return false
|
||||
}
|
||||
return savedPosition || { x: 0, y: 0 }
|
||||
var theme = (apiConfig.theme || staticConfig.theme)
|
||||
var background = (apiConfig.background || staticConfig.background)
|
||||
var logo = (apiConfig.logo || staticConfig.logo)
|
||||
var redirectRootNoLogin = (apiConfig.redirectRootNoLogin || staticConfig.redirectRootNoLogin)
|
||||
var redirectRootLogin = (apiConfig.redirectRootLogin || staticConfig.redirectRootLogin)
|
||||
var chatDisabled = (apiConfig.chatDisabled || staticConfig.chatDisabled)
|
||||
var showWhoToFollowPanel = (apiConfig.showWhoToFollowPanel || staticConfig.showWhoToFollowPanel)
|
||||
var whoToFollowProvider = (apiConfig.whoToFollowProvider || staticConfig.whoToFollowProvider)
|
||||
var whoToFollowLink = (apiConfig.whoToFollowLink || staticConfig.whoToFollowLink)
|
||||
var showInstanceSpecificPanel = (apiConfig.showInstanceSpecificPanel || staticConfig.showInstanceSpecificPanel)
|
||||
var scopeOptionsEnabled = (apiConfig.scopeOptionsEnabled || staticConfig.scopeOptionsEnabled)
|
||||
var collapseMessageWithSubject = (apiConfig.collapseMessageWithSubject || staticConfig.collapseMessageWithSubject)
|
||||
|
||||
store.dispatch('setOption', { name: 'theme', value: theme })
|
||||
store.dispatch('setOption', { name: 'background', value: background })
|
||||
store.dispatch('setOption', { name: 'logo', value: logo })
|
||||
store.dispatch('setOption', { name: 'showWhoToFollowPanel', value: showWhoToFollowPanel })
|
||||
store.dispatch('setOption', { name: 'whoToFollowProvider', value: whoToFollowProvider })
|
||||
store.dispatch('setOption', { name: 'whoToFollowLink', value: whoToFollowLink })
|
||||
store.dispatch('setOption', { name: 'showInstanceSpecificPanel', value: showInstanceSpecificPanel })
|
||||
store.dispatch('setOption', { name: 'scopeOptionsEnabled', value: scopeOptionsEnabled })
|
||||
store.dispatch('setOption', { name: 'collapseMessageWithSubject', value: collapseMessageWithSubject })
|
||||
if (chatDisabled) {
|
||||
store.dispatch('disableChat')
|
||||
}
|
||||
})
|
||||
|
||||
/* eslint-disable no-new */
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
el: '#app',
|
||||
render: h => h(App)
|
||||
const routes = [
|
||||
{ name: 'root',
|
||||
path: '/',
|
||||
redirect: to => {
|
||||
return (store.state.users.currentUser ? redirectRootLogin : redirectRootNoLogin) || '/main/all'
|
||||
}},
|
||||
{ path: '/main/all', component: PublicAndExternalTimeline },
|
||||
{ path: '/main/public', component: PublicTimeline },
|
||||
{ path: '/main/friends', component: FriendsTimeline },
|
||||
{ path: '/tag/:tag', component: TagTimeline },
|
||||
{ name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } },
|
||||
{ name: 'user-profile', path: '/users/:id', component: UserProfile },
|
||||
{ name: 'mentions', path: '/:username/mentions', component: Mentions },
|
||||
{ name: 'settings', path: '/settings', component: Settings },
|
||||
{ name: 'registration', path: '/registration', component: Registration },
|
||||
{ name: 'registration', path: '/registration/:token', component: Registration },
|
||||
{ name: 'friend-requests', path: '/friend-requests', component: FollowRequests },
|
||||
{ name: 'user-settings', path: '/user-settings', component: UserSettings }
|
||||
]
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
routes,
|
||||
scrollBehavior: (to, from, savedPosition) => {
|
||||
if (to.matched.some(m => m.meta.dontScroll)) {
|
||||
return false
|
||||
}
|
||||
return savedPosition || { x: 0, y: 0 }
|
||||
}
|
||||
})
|
||||
|
||||
/* eslint-disable no-new */
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
el: '#app',
|
||||
render: h => h(App)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -192,3 +209,11 @@ window.fetch('/instance/panel.html')
|
|||
.then((html) => {
|
||||
store.dispatch('setOption', { name: 'instanceSpecificPanelContent', value: html })
|
||||
})
|
||||
|
||||
window.fetch('/nodeinfo/2.0.json')
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
const suggestions = data.metadata.suggestions
|
||||
store.dispatch('setOption', { name: 'suggestionsEnabled', value: suggestions.enabled })
|
||||
store.dispatch('setOption', { name: 'suggestionsWeb', value: suggestions.web })
|
||||
})
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { set, delete as del } from 'vue'
|
||||
import StyleSetter from '../services/style_setter/style_setter.js'
|
||||
|
||||
const browserLocale = (window.navigator.language || 'en').split('-')[0]
|
||||
|
||||
const defaultState = {
|
||||
name: 'Pleroma FE',
|
||||
colors: {},
|
||||
|
@ -15,8 +17,10 @@ const defaultState = {
|
|||
hoverPreview: true,
|
||||
pauseOnUnfocused: true,
|
||||
stopGifs: false,
|
||||
replyVisibility: 'all',
|
||||
muteWords: [],
|
||||
highlight: {}
|
||||
highlight: {},
|
||||
interfaceLanguage: browserLocale
|
||||
}
|
||||
|
||||
const config = {
|
||||
|
|
|
@ -37,6 +37,7 @@ const CHANGE_PASSWORD_URL = '/api/pleroma/change_password'
|
|||
const FOLLOW_REQUESTS_URL = '/api/pleroma/friend_requests'
|
||||
const APPROVE_USER_URL = '/api/pleroma/friendships/approve'
|
||||
const DENY_USER_URL = '/api/pleroma/friendships/deny'
|
||||
const SUGGESTIONS_URL = '/api/v1/suggestions'
|
||||
|
||||
import { each, map } from 'lodash'
|
||||
import 'whatwg-fetch'
|
||||
|
@ -372,7 +373,7 @@ const unretweet = ({ id, credentials }) => {
|
|||
})
|
||||
}
|
||||
|
||||
const postStatus = ({credentials, status, spoilerText, visibility, mediaIds, inReplyToStatusId}) => {
|
||||
const postStatus = ({credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId}) => {
|
||||
const idsText = mediaIds.join(',')
|
||||
const form = new FormData()
|
||||
|
||||
|
@ -380,6 +381,7 @@ const postStatus = ({credentials, status, spoilerText, visibility, mediaIds, inR
|
|||
form.append('source', 'Pleroma FE')
|
||||
if (spoilerText) form.append('spoiler_text', spoilerText)
|
||||
if (visibility) form.append('visibility', visibility)
|
||||
if (sensitive) form.append('sensitive', sensitive)
|
||||
form.append('media_ids', idsText)
|
||||
if (inReplyToStatusId) {
|
||||
form.append('in_reply_to_status_id', inReplyToStatusId)
|
||||
|
@ -454,6 +456,12 @@ const fetchMutes = ({credentials}) => {
|
|||
}).then((data) => data.json())
|
||||
}
|
||||
|
||||
const suggestions = ({credentials}) => {
|
||||
return fetch(SUGGESTIONS_URL, {
|
||||
headers: authHeaders(credentials)
|
||||
}).then((data) => data.json())
|
||||
}
|
||||
|
||||
const apiService = {
|
||||
verifyCredentials,
|
||||
fetchTimeline,
|
||||
|
@ -487,7 +495,8 @@ const apiService = {
|
|||
changePassword,
|
||||
fetchFollowRequests,
|
||||
approveUser,
|
||||
denyUser
|
||||
denyUser,
|
||||
suggestions
|
||||
}
|
||||
|
||||
export default apiService
|
||||
|
|
|
@ -25,6 +25,7 @@ const fetchAndUpdate = ({store, credentials, older = false}) => {
|
|||
.then((notifications) => {
|
||||
update({store, notifications, older})
|
||||
}, () => store.dispatch('setNotificationsError', { value: true }))
|
||||
.catch(() => store.dispatch('setNotificationsError', { value: true }))
|
||||
}
|
||||
|
||||
const startFetching = ({credentials, store}) => {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { map } from 'lodash'
|
||||
import apiService from '../api/api.service.js'
|
||||
|
||||
const postStatus = ({ store, status, spoilerText, visibility, media = [], inReplyToStatusId = undefined }) => {
|
||||
const postStatus = ({ store, status, spoilerText, visibility, sensitive, media = [], inReplyToStatusId = undefined }) => {
|
||||
const mediaIds = map(media, 'id')
|
||||
|
||||
return apiService.postStatus({credentials: store.state.users.currentUser.credentials, status, spoilerText, visibility, mediaIds, inReplyToStatusId})
|
||||
return apiService.postStatus({credentials: store.state.users.currentUser.credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId})
|
||||
.then((data) => data.json())
|
||||
.then((data) => {
|
||||
if (!data.error) {
|
||||
|
|
|
@ -3081,6 +3081,10 @@ isexe@^2.0.0:
|
|||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
|
||||
iso-639-1@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.0.3.tgz#72dd3448ac5629c271628c5ac566369428d6ccd0"
|
||||
|
||||
isobject@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
|
||||
|
|
Loading…
Add table
Reference in a new issue