Compare commits

...

34 Commits

Author SHA1 Message Date
Vivian Lim 12fc8759c4 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into snoot 2018-06-25 18:07:42 -07:00
lambda c07adb7121 Merge branch 'patch-1' into 'develop'
Update messages.js / tiny typofix in fr version

See merge request pleroma/pleroma-fe!288
2018-06-25 06:07:47 +00:00
lambda 090efda770 Merge branch 'feature/status-scope-improvements-translation' into 'develop'
src/i18n/messages.js: French Translation for Post Scope UI tooltips

See merge request pleroma/pleroma-fe!287
2018-06-25 06:07:23 +00:00
goofy c2f6227092 Update messages.js / tiny typofix in fr version 2018-06-24 14:18:43 +00:00
Haelwenn (lanodan) Monnier 6da86599a9
src/i18n/messages.js: French Translation for Post Scope UI tooltips
Co-authored-by: goofy
2018-06-24 16:14:47 +02:00
lambda a5d6da41c6 Merge branch 'feature/status-scope-improvements' into 'develop'
Improve Post Scope UI

See merge request pleroma/pleroma-fe!286
2018-06-24 13:49:32 +00:00
Ole Bertram 44428e8b09
Add warning/info text on appriopriate status scopes 2018-06-23 22:10:15 +02:00
Ole Bertram 05bc6fa8e8
Add title text with description to scope icons 2018-06-23 22:09:13 +02:00
lambda a425cfd044 Merge branch 'feature/unrepeats' into 'develop'
Add unretweet support

Closes #103

See merge request pleroma/pleroma-fe!284
2018-06-19 09:23:55 +00:00
Francis Dinh 556eb4b8a3 add unretweet action to statuses.js 2018-06-14 17:17:36 -04:00
Francis Dinh d05fcfa1a8 Add unretweet support 2018-06-14 05:00:11 -04:00
Roger Braun d4f5b3feec Use parents scope if available. 2018-06-12 19:28:48 +02:00
lambda 7707048bff Merge branch 'feature/update-de-translation' into 'develop'
updated german translation

See merge request pleroma/pleroma-fe!269
2018-06-12 17:09:02 +00:00
lambda 0683e37fa4 Merge branch 'feature/update-russian-translation' into 'develop'
Update Russian translation

See merge request pleroma/pleroma-fe!270
2018-06-12 17:03:24 +00:00
lambda 97ae186aaa Merge branch 'improve-settings-ui' into 'develop'
Improve user settings ui

See merge request pleroma/pleroma-fe!273
2018-06-12 17:01:35 +00:00
lambda 5d59028ef7 Merge branch 'patch-1' into 'develop'
Hebrew Translation of "placeholder"

See merge request pleroma/pleroma-fe!278
2018-06-12 16:57:47 +00:00
lambda 6ea5cfe71e Merge branch 'feature/locked-accounts' into 'develop'
Feature/locked accounts

See merge request pleroma/pleroma-fe!274
2018-06-12 16:57:18 +00:00
lambda 2330170d23 Merge branch 'i18n/change-content-warning-to-subject' into 'develop'
messages: rename content warning to subject

See merge request pleroma/pleroma-fe!280
2018-06-12 16:56:34 +00:00
William Pitcock c155110eed messages: rename content warning to subject 2018-06-08 18:47:21 +00:00
Artik Banana d766125eca Update messages.js 2018-06-08 14:08:07 +00:00
William Pitcock d7d787b84c user card: show that the account is locked if it is 2018-06-07 02:16:30 +00:00
William Pitcock 7389f07115 follow requests: refactor to properly leverage vuex 2018-06-07 01:24:31 +00:00
William Pitcock fd25f68741 config: fix typo 2018-06-07 01:13:58 +00:00
William Pitcock f3a27764aa add follow requests UI 2018-06-07 00:58:44 +00:00
William Pitcock b8d0a6a0ba backend interactor service: add approveUser and denyUser functions 2018-06-07 00:29:13 +00:00
William Pitcock 2cf28acfd1 api: add approveUser and denyUser functions 2018-06-07 00:29:01 +00:00
William Pitcock 4efb528a52 backend interactor service: implement fetchFollowRequests() 2018-06-06 22:29:02 +00:00
William Pitcock 4e64514aa9 api: add fetchFollowRequests() 2018-06-06 22:26:24 +00:00
Sebastian Huebner fb0f9f99af corrected a typo and changed/shortend delete_account_error text 2018-06-04 10:58:05 +02:00
User 32d7646db1 Fix the height of file inputs 2018-05-29 21:44:45 +02:00
User 890312a0dc Visually separate the settings items 2018-05-29 21:34:19 +02:00
William Pitcock 7a08ba43e2 user settings: enable locking/unlocking an account 2018-05-29 14:19:28 +00:00
dtluna 3a227cb3b4 Update Russian translation 2018-05-26 12:16:22 +03:00
Sebastian Huebner 5b699bb7fb updated german translation 2018-05-25 11:23:31 +02:00
20 changed files with 253 additions and 38 deletions

View File

@ -23,12 +23,12 @@ module.exports = {
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'htts://localhost:4000/',
target: 'http://localhost:4000/',
changeOrigin: true,
cookieDomainRewrite: 'localhost'
},
'/socket': {
target: 'htts://localhost:4000/',
target: 'http://localhost:4000/',
changeOrigin: true,
cookieDomainRewrite: 'localhost',
ws: true

View File

@ -0,0 +1,23 @@
import UserCard from '../user_card/user_card.vue'
const FollowRequests = {
components: {
UserCard
},
created () {
this.updateRequests()
},
computed: {
requests () {
return this.$store.state.api.followRequests
}
},
methods: {
updateRequests () {
this.$store.state.api.backendInteractor.fetchFollowRequests()
.then((requests) => { this.$store.commit('setFollowRequests', requests) })
}
}
}
export default FollowRequests

View File

@ -0,0 +1,12 @@
<template>
<div class="settings panel panel-default">
<div class="panel-heading">
{{$t('nav.friend_requests')}}
</div>
<div class="panel-body">
<user-card v-for="request in requests" :key="request.id" :user="request" :showFollows="false" :showApproval="true"></user-card>
</div>
</div>
</template>
<script src="./follow_requests.js"></script>

View File

@ -12,6 +12,11 @@
{{ $t("nav.mentions") }}
</router-link>
</li>
<li v-if='currentUser && currentUser.locked'>
<router-link to='/friend-requests'>
{{ $t("nav.friend_requests") }}
</router-link>
</li>
<li>
<router-link to='/main/public'>
{{ $t("nav.public_tl") }}

View File

@ -23,7 +23,8 @@ const PostStatusForm = {
props: [
'replyTo',
'repliedUser',
'attentions'
'attentions',
'messageScope'
],
components: {
MediaUpload
@ -49,7 +50,7 @@ const PostStatusForm = {
newStatus: {
status: statusText,
files: [],
visibility: null
visibility: this.messageScope || 'public'
},
caret: 0
}

View File

@ -2,6 +2,14 @@
<div class="post-status-form">
<form @submit.prevent="postStatus(newStatus)">
<div class="form-group" >
<i18n
v-if="!this.$store.state.users.currentUser.locked && this.newStatus.visibility == 'private'"
path="post_status.account_not_locked_warning"
tag="p"
class="visibility-notice">
<router-link to="/user-settings">{{ $t('post_status.account_not_locked_warning_link') }}</router-link>
</i18n>
<p v-if="this.newStatus.visibility == 'direct'" class="visibility-notice">{{ $t('post_status.direct_warning') }}</p>
<input
v-if="scopeOptionsEnabled"
type="text"
@ -25,10 +33,10 @@
@paste="paste">
</textarea>
<div v-if="scopeOptionsEnabled" class="visibility-tray">
<i v-on:click="changeVis('direct')" class="icon-mail-alt" :class="vis.direct"></i>
<i v-on:click="changeVis('private')" class="icon-lock" :class="vis.private"></i>
<i v-on:click="changeVis('unlisted')" class="icon-lock-open-alt" :class="vis.unlisted"></i>
<i v-on:click="changeVis('public')" class="icon-globe" :class="vis.public"></i>
<i v-on:click="changeVis('direct')" class="icon-mail-alt" :class="vis.direct" :title="$t('post_status.scope.direct')"></i>
<i v-on:click="changeVis('private')" class="icon-lock" :class="vis.private" :title="$t('post_status.scope.private')"></i>
<i v-on:click="changeVis('unlisted')" class="icon-lock-open-alt" :class="vis.unlisted" :title="$t('post_status.scope.unlisted')"></i>
<i v-on:click="changeVis('public')" class="icon-globe" :class="vis.public" :title="$t('post_status.scope.public')"></i>
</div>
</div>
<div style="position:relative;" v-if="candidates">
@ -102,6 +110,14 @@
}
}
.visibility-notice {
padding: .5em;
border: 1px solid $fallback--faint;
border: 1px solid var(--faint, $fallback--faint);
border-radius: $fallback--inputRadius;
border-radius: var(--inputRadius, $fallback--inputRadius);
}
.post-status-form, .login {
.form-bottom {
display: flex;

View File

@ -9,6 +9,8 @@ const RetweetButton = {
retweet () {
if (!this.status.repeated) {
this.$store.dispatch('retweet', {id: this.status.id})
} else {
this.$store.dispatch('unretweet', {id: this.status.id})
}
this.animated = true
setTimeout(() => {
@ -20,6 +22,7 @@ const RetweetButton = {
classes () {
return {
'retweeted': this.status.repeated,
'retweeted-empty': !this.status.repeated,
'animate-spin': this.animated
}
}

View File

@ -57,7 +57,10 @@
@import '../../_variables.scss';
.setting-item {
border-bottom: 2px solid var(--btn, $fallback--btn);
margin: 1em 1em 1.4em;
padding-bottom: 1.4em;
textarea {
width: 100%;

View File

@ -96,7 +96,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" v-on:posted="toggleReplying"/>
<post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" :message-scope="status.visibility" v-on:posted="toggleReplying"/>
</div>
</template>
</div>

View File

@ -3,7 +3,8 @@ import UserCardContent from '../user_card_content/user_card_content.vue'
const UserCard = {
props: [
'user',
'showFollows'
'showFollows',
'showApproval'
],
data () {
return {
@ -16,6 +17,14 @@ const UserCard = {
methods: {
toggleUserExpanded () {
this.userExpanded = !this.userExpanded
},
approveUser () {
this.$store.state.api.backendInteractor.approveUser(this.user.id)
this.$store.dispatch('removeFollowRequest', this.user)
},
denyUser () {
this.$store.state.api.backendInteractor.denyUser(this.user.id)
this.$store.dispatch('removeFollowRequest', this.user)
}
}
}

View File

@ -15,6 +15,10 @@
</div>
<a :href="user.statusnet_profile_url" target="blank"><div class="user-screen-name">@{{ user.screen_name }}</div></a>
</div>
<div class="approval" v-if="showApproval">
<button class="btn btn-default" @click="approveUser">{{ $t('user_card.approve') }}</button>
<button class="btn btn-default" @click="denyUser">{{ $t('user_card.deny') }}</button>
</div>
</div>
</template>
@ -75,4 +79,11 @@
margin-bottom: 0;
}
}
.approval {
button {
width: 100%;
margin-bottom: 0.5em;
}
}
</style>

View File

@ -15,7 +15,7 @@
<div class="name-and-screen-name">
<div :title="user.name" class='user-name'>{{user.name}}</div>
<router-link class='user-screen-name':to="{ name: 'user-profile', params: { id: user.id } }">
<span>@{{user.screen_name}}</span>
<span>@{{user.screen_name}}</span><span v-if="user.locked"><i class="icon icon-lock"></i></span>
<span class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span>
</router-link>
</div>

View File

@ -5,6 +5,7 @@ const UserSettings = {
return {
newname: this.$store.state.users.currentUser.name,
newbio: this.$store.state.users.currentUser.description,
newlocked: this.$store.state.users.currentUser.locked,
followList: null,
followImportError: false,
followsImported: false,
@ -34,7 +35,8 @@ const UserSettings = {
updateProfile () {
const name = this.newname
const description = this.newbio
this.$store.state.api.backendInteractor.updateProfile({params: {name, description}}).then((user) => {
const locked = this.newlocked
this.$store.state.api.backendInteractor.updateProfile({params: {name, description, locked}}).then((user) => {
if (!user.error) {
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)

View File

@ -5,15 +5,19 @@
</div>
<div class="panel-body profile-edit">
<div class="setting-item">
<h3>{{$t('settings.name_bio')}}</h3>
<h2>{{$t('settings.name_bio')}}</h2>
<p>{{$t('settings.name')}}</p>
<input class='name-changer' id='username' v-model="newname"></input>
<p>{{$t('settings.bio')}}</p>
<textarea class="bio" v-model="newbio"></textarea>
<div class="setting-item">
<input type="checkbox" v-model="newlocked" id="account-locked">
<label for="account-locked">{{$t('settings.lock_account_description')}}</label>
</div>
<button :disabled='newname.length <= 0' class="btn btn-default" @click="updateProfile">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h3>{{$t('settings.avatar')}}</h3>
<h2>{{$t('settings.avatar')}}</h2>
<p>{{$t('settings.current_avatar')}}</p>
<img :src="user.profile_image_url_original" class="old-avatar"></img>
<p>{{$t('settings.set_new_avatar')}}</p>
@ -26,7 +30,7 @@
<button class="btn btn-default" v-else-if="previews[0]" @click="submitAvatar">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h3>{{$t('settings.profile_banner')}}</h3>
<h2>{{$t('settings.profile_banner')}}</h2>
<p>{{$t('settings.current_profile_banner')}}</p>
<img :src="user.cover_photo" class="banner"></img>
<p>{{$t('settings.set_new_profile_banner')}}</p>
@ -39,7 +43,7 @@
<button class="btn btn-default" v-else-if="previews[1]" @click="submitBanner">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h3>{{$t('settings.profile_background')}}</h3>
<h2>{{$t('settings.profile_background')}}</h2>
<p>{{$t('settings.set_new_profile_background')}}</p>
<img class="bg" v-bind:src="previews[2]" v-if="previews[2]">
</img>
@ -50,7 +54,7 @@
<button class="btn btn-default" v-else-if="previews[2]" @click="submitBg">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h3>{{$t('settings.change_password')}}</h3>
<h2>{{$t('settings.change_password')}}</h2>
<div>
<p>{{$t('settings.current_password')}}</p>
<input type="password" v-model="changePasswordInputs[0]">
@ -69,7 +73,7 @@
<p v-if="changePasswordError">{{changePasswordError}}</p>
</div>
<div class="setting-item" v-if="pleromaBackend">
<h3>{{$t('settings.follow_import')}}</h3>
<h2>{{$t('settings.follow_import')}}</h2>
<p>{{$t('settings.import_followers_from_a_csv_file')}}</p>
<form v-model="followImportForm">
<input type="file" ref="followlist" v-on:change="followListChange"></input>
@ -86,15 +90,15 @@
</div>
</div>
<div class="setting-item" v-if="enableFollowsExport">
<h3>{{$t('settings.follow_export')}}</h3>
<h2>{{$t('settings.follow_export')}}</h2>
<button class="btn btn-default" @click="exportFollows">{{$t('settings.follow_export_button')}}</button>
</div>
<div class="setting-item" v-else>
<h3>{{$t('settings.follow_export_processing')}}</h3>
<h2>{{$t('settings.follow_export_processing')}}</h2>
</div>
<hr>
<div class="setting-item">
<h3>{{$t('settings.delete_account')}}</h3>
<h2>{{$t('settings.delete_account')}}</h2>
<p v-if="!deletingAccount">{{$t('settings.delete_account_description')}}</p>
<div v-if="deletingAccount">
<p>{{$t('settings.delete_account_instructions')}}</p>
@ -121,6 +125,7 @@
input[type=file] {
padding: 5px;
height: auto;
}
.banner {

View File

@ -48,7 +48,8 @@ const de = {
settings: 'Einstellungen',
theme: 'Farbschema',
presets: 'Voreinstellungen',
theme_help: 'Benutze HTML Farbcodes (#rrggbb) um dein Farbschema anzupassen.',
theme_help: 'Benutze HTML Farbcodes (#rrggbb) um dein Farbschema anzupassen',
radii_help: 'Kantenrundung (in Pixel) der Oberfläche anpassen',
background: 'Hintergrund',
foreground: 'Vordergrund',
text: 'Text',
@ -58,6 +59,7 @@ const de = {
cOrange: 'Orange (Favorisieren)',
cGreen: 'Grün (Retweet)',
btnRadius: 'Buttons',
inputRadius: 'Eingabefelder',
panelRadius: 'Panel',
avatarRadius: 'Avatare',
avatarAltRadius: 'Avatare (Benachrichtigungen)',
@ -76,7 +78,20 @@ const de = {
follow_import: 'Folgeliste importieren',
import_followers_from_a_csv_file: 'Importiere Kontakte, denen du folgen möchtest, aus einer CSV-Datei',
follows_imported: 'Folgeliste importiert! Die Bearbeitung kann eine Zeit lang dauern.',
follow_import_error: 'Fehler beim importieren der Folgeliste'
follow_import_error: 'Fehler beim importieren der Folgeliste',
delete_account: 'Account löschen',
delete_account_description: 'Lösche deinen Account und alle deine Nachrichten dauerhaft.',
delete_account_instructions: 'Tippe dein Passwort unten in das Feld ein um die Löschung deines Accounts zu bestätigen.',
delete_account_error: 'Es ist ein Fehler beim löschen deines Accounts aufgetreten. Tritt dies weiterhin auf, wende dich an den Administrator der Instanz.',
follow_export: 'Folgeliste exportieren',
follow_export_processing: 'In Bearbeitung. Die Liste steht gleich zum herunterladen bereit.',
follow_export_button: 'Liste (.csv) erstellen',
change_password: 'Passwort ändern',
current_password: 'Aktuelles Passwort',
new_password: 'Neues Passwort',
confirm_new_password: 'Neues Passwort bestätigen',
changed_password: 'Passwort erfolgreich geändert!',
change_password_error: 'Es gab ein Problem bei der Änderung des Passworts.'
},
notifications: {
notifications: 'Benachrichtigungen',
@ -102,7 +117,16 @@ const de = {
},
post_status: {
posting: 'Veröffentlichen',
default: 'Sitze gerade im Hofbräuhaus.'
default: 'Sitze gerade im Hofbräuhaus.',
account_not_locked_warning: 'Dein Profil ist nicht {0}. Wer dir folgen will, kann das jederzeit tun und dann auch deine privaten Beiträge sehen.',
account_not_locked_warning_link: 'gesperrt',
direct_warning: 'Dieser Beitrag wird nur für die erwähnten Nutzer sichtbar sein.',
scope: {
public: 'Öffentlich - Beitrag an öffentliche Zeitleisten',
unlisted: 'Nicht gelistet - Nicht in öffentlichen Zeitleisten anzeigen',
private: 'Nur Folgende - Beitrag nur an Folgende',
direct: 'Direkt - Beitrag nur an erwähnte Profile'
}
},
finder: {
find_user: 'Finde Benutzer',
@ -220,7 +244,8 @@ const en = {
timeline: 'Timeline',
mentions: 'Mentions',
public_tl: 'Public Timeline',
twkn: 'The Whole Known Network'
twkn: 'The Whole Known Network',
friend_requests: 'Follow Requests'
},
user_card: {
follows_you: 'Follows you!',
@ -234,7 +259,9 @@ const en = {
followers: 'Followers',
followees: 'Following',
per_day: 'per day',
remote_follow: 'Remote follow'
remote_follow: 'Remote follow',
approve: 'Approve',
deny: 'Deny'
},
timeline: {
show_new: 'Show new',
@ -304,7 +331,8 @@ const en = {
new_password: 'New password',
confirm_new_password: 'Confirm new password',
changed_password: 'Password changed successfully!',
change_password_error: 'There was an issue changing your password.'
change_password_error: 'There was an issue changing your password.',
lock_account_description: 'Restrict your account to approved followers only'
},
notifications: {
notifications: 'Notifications',
@ -331,7 +359,16 @@ const en = {
post_status: {
posting: 'Posting',
content_warning: 'Content warning (optional)',
default: 'whaaat\'s up gamers i\'m here with slap chop'
default: 'whaaat\'s up gamers i\'m here with slap chop',
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.',
scope: {
public: 'Public - Post to public timelines',
unlisted: 'Unlisted - Do not post to public timelines',
private: 'Followers-only - Post to followers only',
direct: 'Direct - Post to mentioned users only'
}
},
finder: {
find_user: 'Find user',
@ -885,7 +922,7 @@ const fr = {
settings: 'Paramètres',
theme: 'Thème',
filtering: 'Filtre',
filtering_explanation: 'Tout les statuts contenant ces mots seront masqués. Un mot par ligne.',
filtering_explanation: 'Tous les statuts contenant ces mots seront masqués. Un mot par ligne.',
attachments: 'Pièces jointes',
hide_attachments_in_tl: 'Masquer les pièces jointes dans le journal',
hide_attachments_in_convo: 'Masquer les pièces jointes dans les conversations',
@ -894,7 +931,7 @@ const fr = {
reply_link_preview: 'Afficher un aperçu lors du survol de liens vers une réponse',
presets: 'Thèmes prédéfinis',
theme_help: 'Spécifiez des codes couleur hexadécimaux (#aabbcc) pour personnaliser les couleurs du thème',
background: 'Arrière plan',
background: 'Arrière-plan',
foreground: 'Premier plan',
text: 'Texte',
links: 'Liens',
@ -905,7 +942,7 @@ const fr = {
follow_import_error: 'Erreur lors de l\'importation des abonnements.',
follow_export: 'Exporter les abonnements',
follow_export_button: 'Exporter les abonnements en csv',
follow_export_processing: 'Exportation en cours...',
follow_export_processing: 'Exportation en cours',
cBlue: 'Bleu (Répondre, suivre)',
cRed: 'Rouge (Annuler)',
cOrange: 'Orange (Aimer)',
@ -952,7 +989,16 @@ const fr = {
},
post_status: {
posting: 'Envoi en cours',
default: 'Écrivez ici votre prochain statut.'
default: 'Écrivez ici votre prochain statut.',
account_not_locked_warning: 'Votre compte nest pas {0}. Nimporte qui peut vous suivre pour voir vos billets en Abonné·e·s uniquement.',
account_not_locked_warning_link: 'verrouillé',
direct_warning: 'Ce message sera visible à toutes les personnes mentionnées.',
scope: {
public: 'Publique - Afficher dans les fils publics',
unlisted: 'Non-Listé - Ne pas afficher dans les fils publics',
private: 'Abonné·e·s uniquement - Seul·e·s vos abonné·e·s verront vos billets',
direct: 'Direct - Nenvoyer quaux personnes mentionnées'
}
},
finder: {
find_user: 'Chercher un utilisateur',
@ -1562,7 +1608,20 @@ const ru = {
follow_import: 'Импортировать читаемых',
import_followers_from_a_csv_file: 'Импортировать читаемых из файла .csv',
follows_imported: 'Список читаемых импортирован. Обработка займёт некоторое время..',
follow_import_error: 'Ошибка при импортировании читаемых.'
follow_import_error: 'Ошибка при импортировании читаемых.',
delete_account: 'Удалить аккаунт',
delete_account_description: 'Удалить ваш аккаунт и все ваши сообщения.',
delete_account_instructions: 'Введите ваш пароль в поле ниже для подтверждения удаления.',
delete_account_error: 'Возникла ошибка в процессе удаления вашего аккаунта. Если это повторяется, свяжитесь с администратором вашего сервера.',
follow_export: 'Экспортировать читаемых',
follow_export_processing: 'Ведётся обработка, скоро вам будет предложено загрузить файл',
follow_export_button: 'Экспортировать читаемых в файл .csv',
change_password: 'Сменить пароль',
current_password: 'Текущий пароль',
new_password: 'Новый пароль',
confirm_new_password: 'Подтверждение нового пароля',
changed_password: 'Пароль изменён успешно.',
change_password_error: 'Произошла ошибка при попытке изменить пароль.'
},
notifications: {
notifications: 'Уведомления',
@ -1827,6 +1886,7 @@ const he = {
login: {
login: 'התחבר',
username: 'שם המשתמש',
placeholder: 'למשל lain',
password: 'סיסמה',
register: 'הירשם',
logout: 'התנתק'

View File

@ -12,6 +12,7 @@ import UserProfile from './components/user_profile/user_profile.vue'
import Settings from './components/settings/settings.vue'
import Registration from './components/registration/registration.vue'
import UserSettings from './components/user_settings/user_settings.vue'
import FollowRequests from './components/follow_requests/follow_requests.vue'
import statusesModule from './modules/statuses.js'
import usersModule from './modules/users.js'
@ -118,6 +119,7 @@ window.fetch('/static/config.json')
{ name: 'mentions', path: '/:username/mentions', component: Mentions },
{ name: 'settings', path: '/settings', component: Settings },
{ name: 'registration', path: '/registration', component: Registration },
{ name: 'friend-requests', path: '/friend-requests', component: FollowRequests },
{ name: 'user-settings', path: '/user-settings', component: UserSettings }
]

View File

@ -7,7 +7,8 @@ const api = {
backendInteractor: backendInteractorService(),
fetchers: {},
socket: null,
chatDisabled: false
chatDisabled: false,
followRequests: []
},
mutations: {
setBackendInteractor (state, backendInteractor) {
@ -24,6 +25,9 @@ const api = {
},
setChatDisabled (state, value) {
state.chatDisabled = value
},
setFollowRequests (state, value) {
state.followRequests = value
}
},
actions: {
@ -57,6 +61,10 @@ const api = {
},
disableChat (store) {
store.commit('setChatDisabled', true)
},
removeFollowRequest (store, request) {
let requests = store.state.followRequests.filter((it) => it !== request)
store.commit('setFollowRequests', requests)
}
}
}

View File

@ -388,6 +388,10 @@ const statuses = {
commit('setRetweeted', { status, value: true })
apiService.retweet({ id: status.id, credentials: rootState.users.currentUser.credentials })
},
unretweet ({ rootState, commit }, status) {
commit('setRetweeted', { status, value: false })
apiService.unretweet({ id: status.id, credentials: rootState.users.currentUser.credentials })
},
queueFlush ({ rootState, commit }, { timeline, id }) {
commit('queueFlush', { timeline, id })
}

View File

@ -8,6 +8,7 @@ const TAG_TIMELINE_URL = '/api/statusnet/tags/timeline'
const FAVORITE_URL = '/api/favorites/create'
const UNFAVORITE_URL = '/api/favorites/destroy'
const RETWEET_URL = '/api/statuses/retweet'
const UNRETWEET_URL = '/api/statuses/unretweet'
const STATUS_UPDATE_URL = '/api/statuses/update.json'
const STATUS_DELETE_URL = '/api/statuses/destroy'
const STATUS_URL = '/api/statuses/show'
@ -32,6 +33,9 @@ const USER_URL = '/api/users/show.json'
const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import'
const DELETE_ACCOUNT_URL = '/api/pleroma/delete_account'
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'
import { each, map } from 'lodash'
import 'whatwg-fetch'
@ -127,11 +131,13 @@ const updateBanner = ({credentials, params}) => {
const updateProfile = ({credentials, params}) => {
let url = PROFILE_UPDATE_URL
console.log(params)
const form = new FormData()
each(params, (value, key) => {
if (key === 'description' || /* Always include description, because it might be empty */
value) {
/* Always include description and locked, because it might be empty or false */
if (key === 'description' || key === 'locked' || value) {
form.append(key, value)
}
})
@ -216,6 +222,22 @@ const unblockUser = ({id, credentials}) => {
}).then((data) => data.json())
}
const approveUser = ({id, credentials}) => {
let url = `${APPROVE_USER_URL}?user_id=${id}`
return fetch(url, {
headers: authHeaders(credentials),
method: 'POST'
}).then((data) => data.json())
}
const denyUser = ({id, credentials}) => {
let url = `${DENY_USER_URL}?user_id=${id}`
return fetch(url, {
headers: authHeaders(credentials),
method: 'POST'
}).then((data) => data.json())
}
const fetchUser = ({id, credentials}) => {
let url = `${USER_URL}?user_id=${id}`
return fetch(url, { headers: authHeaders(credentials) })
@ -240,6 +262,12 @@ const fetchAllFollowing = ({username, credentials}) => {
.then((data) => data.json())
}
const fetchFollowRequests = ({credentials}) => {
const url = FOLLOW_REQUESTS_URL
return fetch(url, { headers: authHeaders(credentials) })
.then((data) => data.json())
}
const fetchConversation = ({id, credentials}) => {
let url = `${CONVERSATION_URL}/${id}.json?count=100`
return fetch(url, { headers: authHeaders(credentials) })
@ -331,6 +359,13 @@ const retweet = ({ id, credentials }) => {
})
}
const unretweet = ({ id, credentials }) => {
return fetch(`${UNRETWEET_URL}/${id}.json`, {
headers: authHeaders(credentials),
method: 'POST'
})
}
const postStatus = ({credentials, status, spoilerText, visibility, mediaIds, inReplyToStatusId}) => {
const idsText = mediaIds.join(',')
const form = new FormData()
@ -428,6 +463,7 @@ const apiService = {
favorite,
unfavorite,
retweet,
unretweet,
postStatus,
deleteStatus,
uploadMedia,
@ -442,7 +478,10 @@ const apiService = {
externalProfile,
followImport,
deleteAccount,
changePassword
changePassword,
fetchFollowRequests,
approveUser,
denyUser
}
export default apiService

View File

@ -42,6 +42,14 @@ const backendInteractorService = (credentials) => {
return apiService.unblockUser({credentials, id})
}
const approveUser = (id) => {
return apiService.approveUser({credentials, id})
}
const denyUser = (id) => {
return apiService.denyUser({credentials, id})
}
const startFetching = ({timeline, store, userId = false}) => {
return timelineFetcherService.startFetching({timeline, store, credentials, userId})
}
@ -51,6 +59,7 @@ const backendInteractorService = (credentials) => {
}
const fetchMutes = () => apiService.fetchMutes({credentials})
const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials})
const register = (params) => apiService.register(params)
const updateAvatar = ({params}) => apiService.updateAvatar({credentials, params})
@ -87,7 +96,10 @@ const backendInteractorService = (credentials) => {
externalProfile,
followImport,
deleteAccount,
changePassword
changePassword,
fetchFollowRequests,
approveUser,
denyUser
}
return backendInteractorServiceInstance