aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--config/index.js4
-rw-r--r--src/components/follow_requests/follow_requests.js23
-rw-r--r--src/components/follow_requests/follow_requests.vue12
-rw-r--r--src/components/login_form/login_form.vue2
-rw-r--r--src/components/nav_panel/nav_panel.vue5
-rw-r--r--src/components/post_status_form/post_status_form.js23
-rw-r--r--src/components/post_status_form/post_status_form.vue35
-rw-r--r--src/components/settings/settings.vue3
-rw-r--r--src/components/user_card/user_card.js11
-rw-r--r--src/components/user_card/user_card.vue11
-rw-r--r--src/components/user_card_content/user_card_content.vue2
-rw-r--r--src/components/user_settings/user_settings.js4
-rw-r--r--src/components/user_settings/user_settings.vue23
-rw-r--r--src/i18n/messages.js213
-rw-r--r--src/main.js5
-rw-r--r--src/modules/api.js10
-rw-r--r--src/services/api/api.service.js40
-rw-r--r--src/services/backend_interactor_service/backend_interactor_service.js14
-rw-r--r--src/services/status_poster/status_poster.service.js4
-rw-r--r--static/config.json3
21 files changed, 411 insertions, 40 deletions
diff --git a/README.md b/README.md
index 2174335a..5a3e2a4b 100644
--- a/README.md
+++ b/README.md
@@ -29,4 +29,6 @@ npm run build
npm run unit
```
-For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
+# Configuration
+
+Edit config.json for configuration. scopeOptionsEnabled gives you input fields for CWs and the scope settings.
diff --git a/config/index.js b/config/index.js
index c48d91b8..5d2cb833 100644
--- a/config/index.js
+++ b/config/index.js
@@ -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
diff --git a/src/components/follow_requests/follow_requests.js b/src/components/follow_requests/follow_requests.js
new file mode 100644
index 00000000..11a228aa
--- /dev/null
+++ b/src/components/follow_requests/follow_requests.js
@@ -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
diff --git a/src/components/follow_requests/follow_requests.vue b/src/components/follow_requests/follow_requests.vue
new file mode 100644
index 00000000..87dc4194
--- /dev/null
+++ b/src/components/follow_requests/follow_requests.vue
@@ -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>
diff --git a/src/components/login_form/login_form.vue b/src/components/login_form/login_form.vue
index 67fa95a8..b7fed48a 100644
--- a/src/components/login_form/login_form.vue
+++ b/src/components/login_form/login_form.vue
@@ -8,7 +8,7 @@
<form v-on:submit.prevent='submit(user)' class='login-form'>
<div class='form-group'>
<label for='username'>{{$t('login.username')}}</label>
- <input :disabled="loggingIn" v-model='user.username' class='form-control' id='username' placeholder='e.g. lain'>
+ <input :disabled="loggingIn" v-model='user.username' class='form-control' id='username' v-bind:placeholder="$t('login.placeholder')">
</div>
<div class='form-group'>
<label for='password'>{{$t('login.password')}}</label>
diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue
index 2e1a6c7a..0b188f9a 100644
--- a/src/components/nav_panel/nav_panel.vue
+++ b/src/components/nav_panel/nav_panel.vue
@@ -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") }}
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index e6742580..0597d652 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -48,12 +48,21 @@ const PostStatusForm = {
highlighted: 0,
newStatus: {
status: statusText,
- files: []
+ files: [],
+ visibility: 'public'
},
caret: 0
}
},
computed: {
+ vis () {
+ return {
+ public: { selected: this.newStatus.visibility === 'public' },
+ unlisted: { selected: this.newStatus.visibility === 'unlisted' },
+ private: { selected: this.newStatus.visibility === 'private' },
+ direct: { selected: this.newStatus.visibility === 'direct' }
+ }
+ },
candidates () {
const firstchar = this.textAtCaret.charAt(0)
if (firstchar === '@') {
@@ -118,6 +127,9 @@ const PostStatusForm = {
},
isOverLengthLimit () {
return this.hasStatusLengthLimit && (this.statusLength > this.statusLengthLimit)
+ },
+ scopeOptionsEnabled () {
+ return this.$store.state.config.scopeOptionsEnabled
}
},
methods: {
@@ -185,6 +197,8 @@ const PostStatusForm = {
this.posting = true
statusPoster.postStatus({
status: newStatus.status,
+ spoilerText: newStatus.spoilerText || null,
+ visibility: newStatus.visibility,
media: newStatus.files,
store: this.$store,
inReplyToStatusId: this.replyTo
@@ -192,7 +206,8 @@ const PostStatusForm = {
if (!data.error) {
this.newStatus = {
status: '',
- files: []
+ files: [],
+ visibility: newStatus.visibility
}
this.$emit('posted')
let el = this.$el.querySelector('textarea')
@@ -239,6 +254,7 @@ const PostStatusForm = {
e.dataTransfer.dropEffect = 'copy'
},
resize (e) {
+ if (!e.target) { return }
const vertPadding = Number(window.getComputedStyle(e.target)['padding-top'].substr(0, 1)) +
Number(window.getComputedStyle(e.target)['padding-bottom'].substr(0, 1))
e.target.style.height = 'auto'
@@ -249,6 +265,9 @@ const PostStatusForm = {
},
clearError () {
this.error = null
+ },
+ changeVis (visibility) {
+ this.newStatus.visibility = visibility
}
}
}
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 28dd227e..802d51ed 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -2,6 +2,12 @@
<div class="post-status-form">
<form @submit.prevent="postStatus(newStatus)">
<div class="form-group" >
+ <input
+ v-if="scopeOptionsEnabled"
+ type="text"
+ :placeholder="$t('post_status.content_warning')"
+ v-model="newStatus.spoilerText"
+ class="form-cw">
<textarea
ref="textarea"
@click="setCaret"
@@ -18,6 +24,12 @@
@input="resize"
@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>
+ </div>
</div>
<div style="position:relative;" v-if="candidates">
<div class="autocomplete-panel">
@@ -79,6 +91,17 @@
}
}
+.post-status-form .visibility-tray {
+ font-size: 1.2em;
+ padding: 3px;
+ cursor: pointer;
+
+ .selected {
+ color: $fallback--lightFg;
+ color: var(--lightFg, $fallback--lightFg);
+ }
+}
+
.post-status-form, .login {
.form-bottom {
display: flex;
@@ -143,7 +166,15 @@
line-height:24px;
}
- form textarea {
+ form textarea.form-cw {
+ line-height:16px;
+ resize: none;
+ overflow: hidden;
+ transition: min-height 200ms 100ms;
+ min-height: 1px;
+ }
+
+ form textarea.form-control {
line-height:16px;
resize: none;
overflow: hidden;
@@ -152,7 +183,7 @@
box-sizing: content-box;
}
- form textarea:focus {
+ form textarea.form-control:focus {
min-height: 48px;
}
diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue
index b4514ba1..6245e758 100644
--- a/src/components/settings/settings.vue
+++ b/src/components/settings/settings.vue
@@ -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%;
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index a7a871c3..a019627a 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -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)
}
}
}
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 51d6965f..6478a65f 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -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>
diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index c120df9a..09e91271 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -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>
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index b6026e18..443e63dd 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -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)
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index fbf3f651..881b0fa1 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -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 {
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index 5009418f..3a9f2e63 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -103,6 +103,7 @@ const de = {
login: {
login: 'Anmelden',
username: 'Benutzername',
+ placeholder: 'z.B. lain',
password: 'Passwort',
register: 'Registrieren',
logout: 'Abmelden'
@@ -199,6 +200,7 @@ const fi = {
login: {
login: 'Kirjaudu sisään',
username: 'Käyttäjänimi',
+ placeholder: 'esim. lain',
password: 'Salasana',
register: 'Rekisteröidy',
logout: 'Kirjaudu ulos'
@@ -233,7 +235,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!',
@@ -247,7 +250,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',
@@ -317,7 +322,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',
@@ -329,6 +335,7 @@ const en = {
login: {
login: 'Log in',
username: 'Username',
+ placeholder: 'e.g. lain',
password: 'Password',
register: 'Register',
logout: 'Log out'
@@ -342,6 +349,7 @@ const en = {
},
post_status: {
posting: 'Posting',
+ content_warning: 'Subject (optional)',
default: 'Just landed in L.A.'
},
finder: {
@@ -448,6 +456,7 @@ const eo = {
login: {
login: 'Saluti',
username: 'Salutnomo',
+ placeholder: 'ekz. lain',
password: 'Pasvorto',
register: 'Registriĝi',
logout: 'Adiaŭi'
@@ -535,6 +544,7 @@ const et = {
login: {
login: 'Logi sisse',
username: 'Kasutajanimi',
+ placeholder: 'nt lain',
password: 'Parool',
register: 'Registreeru',
logout: 'Logi välja'
@@ -618,6 +628,7 @@ const hu = {
login: {
login: 'Bejelentkezés',
username: 'Felhasználó név',
+ placeholder: 'e.g. lain',
password: 'Jelszó',
register: 'Feliratkozás',
logout: 'Kijelentkezés'
@@ -701,6 +712,7 @@ const ro = {
login: {
login: 'Loghează',
username: 'Nume utilizator',
+ placeholder: 'd.e. lain',
password: 'Parolă',
register: 'Înregistrare',
logout: 'Deloghează'
@@ -816,6 +828,7 @@ const ja = {
login: {
login: 'ログイン',
username: 'ユーザー名',
+ placeholder: '例えば lain',
password: 'パスワード',
register: '登録',
logout: 'ログアウト'
@@ -905,10 +918,13 @@ const fr = {
text: 'Texte',
links: 'Liens',
streaming: 'Charger automatiquement les nouveaux statuts lorsque vous êtes au haut de la page',
- follow_import: 'Importer ses abonnements',
- import_followers_from_a_csv_file: 'Importer ses abonnements depuis un fichier csv',
+ follow_import: 'Importer des abonnements',
+ import_followers_from_a_csv_file: 'Importer des abonnements depuis un fichier csv',
follows_imported: 'Abonnements importés ! Le traitement peut prendre un moment.',
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...',
cBlue: 'Bleu (Répondre, suivre)',
cRed: 'Rouge (Annuler)',
cOrange: 'Orange (Aimer)',
@@ -921,7 +937,15 @@ const fr = {
tooltipRadius: 'Info-bulles/alertes ',
attachmentRadius: 'Pièces jointes',
radii_help: 'Vous pouvez ici choisir le niveau d\'arrondi des angles de l\'interface (en pixels)',
- stop_gifs: 'N\'animer les GIFS que lors du survol du curseur de la souris'
+ stop_gifs: 'N\'animer les GIFS que lors du survol du curseur de la souris',
+ change_password: 'Modifier son mot de passe',
+ current_password: 'Mot de passe actuel',
+ new_password: 'Nouveau mot de passe',
+ confirm_new_password: 'Confirmation du nouveau mot de passe',
+ delete_account: 'Supprimer le compte',
+ delete_account_description: 'Supprimer définitivement votre compte et tous vos statuts.',
+ delete_account_instructions: 'Indiquez votre mot de passe ci-dessous pour confirmer la suppression de votre compte.',
+ delete_account_error: 'Il y a eu un problème lors de la tentative de suppression de votre compte. Si le problème persiste, contactez l\'administrateur de cette instance.'
},
notifications: {
notifications: 'Notifications',
@@ -933,6 +957,7 @@ const fr = {
login: {
login: 'Connexion',
username: 'Identifiant',
+ placeholder: 'p.e. lain',
password: 'Mot de passe',
register: 'S\'inscrire',
logout: 'Déconnexion'
@@ -1111,6 +1136,7 @@ const oc = {
login: {
login: 'Connexion',
username: 'Nom d’utilizaire',
+ placeholder: 'e.g. lain',
password: 'Senhal',
register: 'Se marcar',
logout: 'Desconnexion'
@@ -1200,13 +1226,14 @@ const pl = {
cOrange: 'Pomarańczowy (ulubione)',
cGreen: 'Zielony (powtórzenia)',
btnRadius: 'Przyciski',
+ inputRadius: 'Pola tekstowe',
panelRadius: 'Panele',
avatarRadius: 'Awatary',
avatarAltRadius: 'Awatary (powiadomienia)',
tooltipRadius: 'Etykiety/alerty',
attachmentRadius: 'Załączniki',
filtering: 'Filtrowanie',
- filtering_explanation: 'Wszystkie statusy zawierające te słowa będą wyciszone. Jedno słowo na linijkę',
+ filtering_explanation: 'Wszystkie statusy zawierające te słowa będą wyciszone. Jedno słowo na linijkę.',
attachments: 'Załączniki',
hide_attachments_in_tl: 'Ukryj załączniki w osi czasu',
hide_attachments_in_convo: 'Ukryj załączniki w rozmowach',
@@ -1218,7 +1245,20 @@ const pl = {
follow_import: 'Import obserwowanych',
import_followers_from_a_csv_file: 'Importuj obserwowanych z pliku CSV',
follows_imported: 'Obserwowani zaimportowani! Przetwarzanie może trochę potrwać.',
- follow_import_error: 'Błąd przy importowaniu obserwowanych'
+ follow_import_error: 'Błąd przy importowaniu obserwowanych',
+ delete_account: 'Usuń konto',
+ delete_account_description: 'Trwale usuń konto i wszystkie posty.',
+ delete_account_instructions: 'Wprowadź swoje hasło w poniższe pole aby potwierdzić usunięcie konta.',
+ delete_account_error: 'Wystąpił problem z usuwaniem twojego konta. Jeżeli problem powtarza się, poinformuj administratora swojej instancji.',
+ follow_export: 'Eksport obserwowanych',
+ follow_export_processing: 'Przetwarzanie, wkrótce twój plik zacznie się ściągać.',
+ follow_export_button: 'Eksportuj swoją listę obserwowanych do pliku CSV',
+ change_password: 'Zmień hasło',
+ current_password: 'Obecne hasło',
+ new_password: 'Nowe hasło',
+ confirm_new_password: 'Potwierdź nowe hasło',
+ changed_password: 'Hasło zmienione poprawnie!',
+ change_password_error: 'Podczas zmiany hasła wystąpił problem.'
},
notifications: {
notifications: 'Powiadomienia',
@@ -1230,6 +1270,7 @@ const pl = {
login: {
login: 'Zaloguj',
username: 'Użytkownik',
+ placeholder: 'n.p. lain',
password: 'Hasło',
register: 'Zarejestruj',
logout: 'Wyloguj'
@@ -1333,6 +1374,7 @@ const es = {
login: {
login: 'Identificación',
username: 'Usuario',
+ placeholder: 'p.ej. lain',
password: 'Contraseña',
register: 'Registrar',
logout: 'Salir'
@@ -1433,6 +1475,7 @@ const pt = {
login: {
login: 'Entrar',
username: 'Usuário',
+ placeholder: 'p.e. lain',
password: 'Senha',
register: 'Registrar',
logout: 'Sair'
@@ -1538,7 +1581,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: 'Уведомления',
@@ -1550,6 +1606,7 @@ const ru = {
login: {
login: 'Войти',
username: 'Имя пользователя',
+ placeholder: 'e.c. lain',
password: 'Пароль',
register: 'Зарегистрироваться',
logout: 'Выйти'
@@ -1668,6 +1725,7 @@ const nb = {
login: {
login: 'Logg inn',
username: 'Brukernavn',
+ placeholder: 'f. eks lain',
password: 'Passord',
register: 'Registrer',
logout: 'Logg ut'
@@ -1696,6 +1754,140 @@ const nb = {
}
}
+const he = {
+ chat: {
+ title: 'צ\'אט'
+ },
+ nav: {
+ chat: 'צ\'אט מקומי',
+ timeline: 'ציר הזמן',
+ mentions: 'אזכורים',
+ public_tl: 'ציר הזמן הציבורי',
+ twkn: 'כל הרשת הידועה'
+ },
+ user_card: {
+ follows_you: 'עוקב אחריך!',
+ following: 'עוקב!',
+ follow: 'עקוב',
+ blocked: 'חסום!',
+ block: 'חסימה',
+ statuses: 'סטטוסים',
+ mute: 'השתק',
+ muted: 'מושתק',
+ followers: 'עוקבים',
+ followees: 'נעקבים',
+ per_day: 'ליום',
+ remote_follow: 'עקיבה מרחוק'
+ },
+ timeline: {
+ show_new: 'הראה חדש',
+ error_fetching: 'שגיאה בהבאת הודעות',
+ up_to_date: 'עדכני',
+ load_older: 'טען סטטוסים חדשים',
+ conversation: 'שיחה',
+ collapse: 'מוטט',
+ repeated: 'חזר'
+ },
+ settings: {
+ user_settings: 'הגדרות משתמש',
+ name_bio: 'שם ואודות',
+ name: 'שם',
+ bio: 'אודות',
+ avatar: 'תמונת פרופיל',
+ current_avatar: 'תמונת הפרופיל הנוכחית שלך',
+ set_new_avatar: 'קבע תמונת פרופיל חדשה',
+ profile_banner: 'כרזת הפרופיל',
+ current_profile_banner: 'כרזת הפרופיל הנוכחית שלך',
+ set_new_profile_banner: 'קבע כרזת פרופיל חדשה',
+ profile_background: 'רקע הפרופיל',
+ set_new_profile_background: 'קבע רקע פרופיל חדש',
+ settings: 'הגדרות',
+ theme: 'תמה',
+ presets: 'ערכים קבועים מראש',
+ theme_help: 'השתמש בקודי צבע הקס (#אדום-אדום-ירוק-ירוק-כחול-כחול) על מנת להתאים אישית את תמת הצבע שלך.',
+ radii_help: 'קבע מראש עיגול פינות לממשק (בפיקסלים)',
+ background: 'רקע',
+ foreground: 'חזית',
+ text: 'טקסט',
+ links: 'לינקים',
+ cBlue: 'כחול (תגובה, עקיבה)',
+ cRed: 'אדום (ביטול)',
+ cOrange: 'כתום (לייק)',
+ cGreen: 'ירוק (חזרה)',
+ btnRadius: 'כפתורים',
+ inputRadius: 'שדות קלט',
+ panelRadius: 'פאנלים',
+ avatarRadius: 'תמונות פרופיל',
+ avatarAltRadius: 'תמונות פרופיל (התראות)',
+ tooltipRadius: 'טולטיפ \\ התראות',
+ attachmentRadius: 'צירופים',
+ filtering: 'סינון',
+ filtering_explanation: 'כל הסטטוסים הכוללים את המילים הללו יושתקו, אחד לשורה',
+ attachments: 'צירופים',
+ hide_attachments_in_tl: 'החבא צירופים בציר הזמן',
+ hide_attachments_in_convo: 'החבא צירופים בשיחות',
+ nsfw_clickthrough: 'החל החבאת צירופים לא בטוחים לצפיה בעת עבודה בעזרת לחיצת עכבר',
+ stop_gifs: 'נגן-בעת-ריחוף GIFs',
+ autoload: 'החל טעינה אוטומטית בגלילה לתחתית הדף',
+ streaming: 'החל זרימת הודעות אוטומטית בעת גלילה למעלה הדף',
+ reply_link_preview: 'החל תצוגה מקדימה של לינק-תגובה בעת ריחוף עם העכבר',
+ follow_import: 'יבוא עקיבות',
+ import_followers_from_a_csv_file: 'ייבא את הנעקבים שלך מקובץ csv',
+ follows_imported: 'נעקבים יובאו! ייקח זמן מה לעבד אותם.',
+ 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: 'התראות',
+ read: 'קרא!',
+ followed_you: 'עקב אחריך!',
+ favorited_you: 'אהב את הסטטוס שלך',
+ repeated_you: 'חזר על הסטטוס שלך'
+ },
+ login: {
+ login: 'התחבר',
+ username: 'שם המשתמש',
+ placeholder: 'למשל lain',
+ password: 'סיסמה',
+ register: 'הירשם',
+ logout: 'התנתק'
+ },
+ registration: {
+ registration: 'הרשמה',
+ fullname: 'שם תצוגה',
+ email: 'אימייל',
+ bio: 'אודות',
+ password_confirm: 'אישור סיסמה'
+ },
+ post_status: {
+ posting: 'מפרסם',
+ default: 'הרגע נחת ב-ל.א.'
+ },
+ finder: {
+ find_user: 'מציאת משתמש',
+ error_fetching_user: 'שגיאה במציאת משתמש'
+ },
+ general: {
+ submit: 'שלח',
+ apply: 'החל'
+ },
+ user_profile: {
+ timeline_title: 'ציר זמן המשתמש'
+ }
+}
+
const messages = {
de,
fi,
@@ -1712,7 +1904,8 @@ const messages = {
es,
pt,
ru,
- nb
+ nb,
+ he
}
export default messages
diff --git a/src/main.js b/src/main.js
index 3c4a072b..bacd7f6d 100644
--- a/src/main.js
+++ b/src/main.js
@@ -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'
@@ -88,7 +89,7 @@ window.fetch('/api/statusnet/config.json')
window.fetch('/static/config.json')
.then((res) => res.json())
.then((data) => {
- const {theme, background, logo, showWhoToFollowPanel, whoToFollowProvider, whoToFollowLink, showInstanceSpecificPanel} = data
+ const {theme, background, logo, showWhoToFollowPanel, whoToFollowProvider, whoToFollowLink, showInstanceSpecificPanel, scopeOptionsEnabled} = data
store.dispatch('setOption', { name: 'theme', value: theme })
store.dispatch('setOption', { name: 'background', value: background })
store.dispatch('setOption', { name: 'logo', value: logo })
@@ -96,6 +97,7 @@ window.fetch('/static/config.json')
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 })
if (data['chatDisabled']) {
store.dispatch('disableChat')
}
@@ -117,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 }
]
diff --git a/src/modules/api.js b/src/modules/api.js
index c91fb97b..a61340c2 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -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)
}
}
}
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 65761aee..d1659784 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -32,6 +32,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 +130,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 +221,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 +261,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,12 +358,14 @@ const retweet = ({ id, credentials }) => {
})
}
-const postStatus = ({credentials, status, mediaIds, inReplyToStatusId}) => {
+const postStatus = ({credentials, status, spoilerText, visibility, mediaIds, inReplyToStatusId}) => {
const idsText = mediaIds.join(',')
const form = new FormData()
form.append('status', status)
form.append('source', 'Pleroma FE')
+ if (spoilerText) form.append('spoiler_text', spoilerText)
+ if (visibility) form.append('visibility', visibility)
form.append('media_ids', idsText)
if (inReplyToStatusId) {
form.append('in_reply_to_status_id', inReplyToStatusId)
@@ -440,7 +469,10 @@ const apiService = {
externalProfile,
followImport,
deleteAccount,
- changePassword
+ changePassword,
+ fetchFollowRequests,
+ approveUser,
+ denyUser
}
export default apiService
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index 14173558..dbfb54f9 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -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
diff --git a/src/services/status_poster/status_poster.service.js b/src/services/status_poster/status_poster.service.js
index 001ff8a5..3381e9e2 100644
--- a/src/services/status_poster/status_poster.service.js
+++ b/src/services/status_poster/status_poster.service.js
@@ -1,10 +1,10 @@
import { map } from 'lodash'
import apiService from '../api/api.service.js'
-const postStatus = ({ store, status, media = [], inReplyToStatusId = undefined }) => {
+const postStatus = ({ store, status, spoilerText, visibility, media = [], inReplyToStatusId = undefined }) => {
const mediaIds = map(media, 'id')
- return apiService.postStatus({credentials: store.state.users.currentUser.credentials, status, mediaIds, inReplyToStatusId})
+ return apiService.postStatus({credentials: store.state.users.currentUser.credentials, status, spoilerText, visibility, mediaIds, inReplyToStatusId})
.then((data) => data.json())
.then((data) => {
if (!data.error) {
diff --git a/static/config.json b/static/config.json
index 9cdb22d5..4dacfebe 100644
--- a/static/config.json
+++ b/static/config.json
@@ -10,5 +10,6 @@
"whoToFollowProviderDummy2": "https://followlink.osa-p.net/api/get_recommend.json?acct=@{{user}}@{{host}}",
"whoToFollowLink": "https://vinayaka.distsn.org/?{{host}}+{{user}}",
"whoToFollowLinkDummy2": "https://followlink.osa-p.net/recommend.html",
- "showInstanceSpecificPanel": false
+ "showInstanceSpecificPanel": false,
+ "scopeOptionsEnabled": false
}