Prepare for i18n.

This commit is contained in:
Roger Braun 2017-11-07 15:14:37 +01:00
parent 81b0849889
commit 7516cd859f
11 changed files with 142 additions and 52 deletions

View file

@ -24,6 +24,7 @@
"sanitize-html": "^1.13.0", "sanitize-html": "^1.13.0",
"sass-loader": "^4.0.2", "sass-loader": "^4.0.2",
"vue": "^2.3.4", "vue": "^2.3.4",
"vue-i18n": "^7.3.2",
"vue-router": "^2.5.3", "vue-router": "^2.5.3",
"vue-template-compiler": "^2.3.4", "vue-template-compiler": "^2.3.4",
"vue-timeago": "^3.1.2", "vue-timeago": "^3.1.2",

View file

@ -4,22 +4,22 @@
<ul class="base03-border"> <ul class="base03-border">
<li v-if='currentUser'> <li v-if='currentUser'>
<router-link class="base00-background" to='/main/friends'> <router-link class="base00-background" to='/main/friends'>
Timeline {{ $t("nav.timeline") }}
</router-link> </router-link>
</li> </li>
<li v-if='currentUser'> <li v-if='currentUser'>
<router-link class="base00-background" :to="{ name: 'mentions', params: { username: currentUser.screen_name } }"> <router-link class="base00-background" :to="{ name: 'mentions', params: { username: currentUser.screen_name } }">
Mentions {{ $t("nav.mentions") }}
</router-link> </router-link>
</li> </li>
<li> <li>
<router-link class="base00-background" to='/main/public'> <router-link class="base00-background" to='/main/public'>
Public Timeline {{ $t("nav.public_tl") }}
</router-link> </router-link>
</li> </li>
<li> <li>
<router-link class="base00-background" to='/main/all'> <router-link class="base00-background" to='/main/all'>
The Whole Known Network {{ $t("nav.twkn") }}
</router-link> </router-link>
</li> </li>
</ul> </ul>

View file

@ -3,8 +3,8 @@
<div class="panel panel-default base00-background"> <div class="panel panel-default base00-background">
<div class="panel-heading base01-background base04"> <div class="panel-heading base01-background base04">
<span class="unseen-count" v-if="unseenCount">{{unseenCount}}</span> <span class="unseen-count" v-if="unseenCount">{{unseenCount}}</span>
Notifications {{$t('notifications.notifications')}}
<button @click.prevent="markAsSeen" class="base05 base01-background read-button">Read!</button> <button @click.prevent="markAsSeen" class="base05 base01-background read-button">{{$t('notifications.read')}}</button>
</div> </div>
<div class="panel-body base03-border"> <div class="panel-body base03-border">
<div v-for="notification in visibleNotifications" :key="notification" class="notification" :class='{"unseen": !notification.seen}'> <div v-for="notification in visibleNotifications" :key="notification" class="notification" :class='{"unseen": !notification.seen}'>
@ -44,7 +44,7 @@
<i class="fa icon-user-plus lit"></i> <i class="fa icon-user-plus lit"></i>
</h1> </h1>
<div> <div>
<router-link :to="{ name: 'user-profile', params: { id: notification.action.user.id } }">@{{ notification.action.user.screen_name }}</router-link> followed you <router-link :to="{ name: 'user-profile', params: { id: notification.action.user.id } }">@{{ notification.action.user.screen_name }}</router-link> {{$t('notifications.followed_you')}}
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,40 +1,40 @@
<template> <template>
<div class="settings panel panel-default base00-background"> <div class="settings panel panel-default base00-background">
<div class="panel-heading base01-background base04"> <div class="panel-heading base01-background base04">
Settings {{$t('settings.settings')}}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<div class="setting-item"> <div class="setting-item">
<h2>Theme</h2> <h2>{{$t('settings.theme')}}</h2>
<style-switcher></style-switcher> <style-switcher></style-switcher>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<h2>Filtering</h2> <h2>{{$t('settings.filtering')}}</h2>
<p>All notices containing these words will be muted, one per line</p> <p>{{$t('settings.filtering_explanation')}}</p>
<textarea id="muteWords" v-model="muteWordsString"></textarea> <textarea id="muteWords" v-model="muteWordsString"></textarea>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<h2>Attachments</h2> <h2>{{$t('settings.attachments')}}</h2>
<ul class="setting-list"> <ul class="setting-list">
<li> <li>
<input type="checkbox" id="hideAttachments" v-model="hideAttachmentsLocal"> <input type="checkbox" id="hideAttachments" v-model="hideAttachmentsLocal">
<label for="hideAttachments">Hide attachments in timeline</label> <label for="hideAttachments">{{$t('settings.hide_attachments_in_tl')}}</label>
</li> </li>
<li> <li>
<input type="checkbox" id="hideAttachmentsInConv" v-model="hideAttachmentsInConvLocal"> <input type="checkbox" id="hideAttachmentsInConv" v-model="hideAttachmentsInConvLocal">
<label for="hideAttachmentsInConv">Hide attachments in conversations</label> <label for="hideAttachmentsInConv">{{$t('settings.hide_attachments_in_convo')}}</label>
</li> </li>
<li> <li>
<input type="checkbox" id="hideNsfw" v-model="hideNsfwLocal"> <input type="checkbox" id="hideNsfw" v-model="hideNsfwLocal">
<label for="hideNsfw">Enable clickthrough NSFW attachment hiding</label> <label for="hideNsfw">{{$t('settings.nsfw_clickthrough')}}</label>
</li> </li>
<li> <li>
<input type="checkbox" id="autoLoad" v-model="autoLoadLocal"> <input type="checkbox" id="autoLoad" v-model="autoLoadLocal">
<label for="autoLoad">Enable automatic loading when scrolled to the bottom</label> <label for="autoLoad">{{$t('settings.autoload')}}</label>
</li> </li>
<li> <li>
<input type="checkbox" id="hoverPreview" v-model="hoverPreviewLocal"> <input type="checkbox" id="hoverPreview" v-model="hoverPreviewLocal">
<label for="hoverPreview">Enable reply-link preview on mouse hover</label> <label for="hoverPreview">{{$t('settings.reply_link_preview')}}</label>
</li> </li>
</ul> </ul>
</div> </div>

View file

@ -5,20 +5,20 @@
{{title}} {{title}}
</div> </div>
<button @click.prevent="showNewStatuses" class="base05 base01-background loadmore-button" v-if="timeline.newStatusCount > 0 && !timelineError"> <button @click.prevent="showNewStatuses" class="base05 base01-background loadmore-button" v-if="timeline.newStatusCount > 0 && !timelineError">
Show new ({{timeline.newStatusCount}}) {{$t('timeline.show_new')}} ({{timeline.newStatusCount}})
</button> </button>
<div @click.prevent class="base06 error loadmore-text" v-if="timelineError"> <div @click.prevent class="base06 error loadmore-text" v-if="timelineError">
Error fetching updates {{$t('timeline.error_fetching')}}
</div> </div>
<div @click.prevent class="base04 base01-background loadmore-text" v-if="!timeline.newStatusCount > 0 && !timelineError"> <div @click.prevent class="base04 base01-background loadmore-text" v-if="!timeline.newStatusCount > 0 && !timelineError">
Up-to-date {{$t('timeline.up_to_date')}}
</div> </div>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<div class="timeline"> <div class="timeline">
<status-or-conversation v-for="status in timeline.visibleStatuses" :key="status.id" v-bind:statusoid="status"></status-or-conversation> <status-or-conversation v-for="status in timeline.visibleStatuses" :key="status.id" v-bind:statusoid="status"></status-or-conversation>
<a href="#" v-on:click.prevent='fetchOlderStatuses()' v-if="!timeline.loading"> <a href="#" v-on:click.prevent='fetchOlderStatuses()' v-if="!timeline.loading">
<div class="base01-background base03-border new-status-notification text-center">Load older statuses.</div> <div class="base01-background base03-border new-status-notification text-center">{{$t('timeline.load_older')}}</div>
</a> </a>
<div class="base01-background base03-border new-status-notification text-center" v-else>...</div> <div class="base01-background base03-border new-status-notification text-center" v-else>...</div>
</div> </div>
@ -27,7 +27,7 @@
<div class="timeline panel panel-default" v-else-if="viewing == 'followers'"> <div class="timeline panel panel-default" v-else-if="viewing == 'followers'">
<div class="panel-heading timeline-heading base01-background base04"> <div class="panel-heading timeline-heading base01-background base04">
<div class="title"> <div class="title">
Followers {{$t('user_card.followers')}}
</div> </div>
</div> </div>
<div class="panel-body"> <div class="panel-body">
@ -39,7 +39,7 @@
<div class="timeline panel panel-default" v-else-if="viewing == 'friends'"> <div class="timeline panel panel-default" v-else-if="viewing == 'friends'">
<div class="panel-heading timeline-heading base01-background base04"> <div class="panel-heading timeline-heading base01-background base04">
<div class="title"> <div class="title">
Following {{$t('user_card.followees')}}
</div> </div>
</div> </div>
<div class="panel-body"> <div class="panel-body">

View file

@ -10,7 +10,7 @@
<div class="user-name"> <div class="user-name">
{{ user.name }} {{ user.name }}
<span class="follows-you" v-if="!userExpanded && showFollows && user.follows_you"> <span class="follows-you" v-if="!userExpanded && showFollows && user.follows_you">
Follows you! {{ $t('user_card.follows_you') }}
</span> </span>
</div> </div>
<a :href="user.statusnet_profile_url" target="blank"><div class="user-screen-name">@{{ user.screen_name }}</div></a> <a :href="user.statusnet_profile_url" target="blank"><div class="user-screen-name">@{{ user.screen_name }}</div></a>

View file

@ -19,27 +19,31 @@
</div> </div>
<div v-if="isOtherUser" class="user-interactions"> <div v-if="isOtherUser" class="user-interactions">
<div v-if="user.follows_you && loggedIn" class="following base06"> <div v-if="user.follows_you && loggedIn" class="following base06">
Follows you! {{ $t('user_card.follows_you') }}
</div> </div>
<div class="follow" v-if="loggedIn"> <div class="follow" v-if="loggedIn">
<span v-if="user.following"> <span v-if="user.following">
<!--Following them!--> <!--Following them!-->
<button @click="unfollowUser" class="base04 base00-background pressed"> <button @click="unfollowUser" class="base04 base00-background pressed">
Following! {{ $t('user_card.following') }}
</button> </button>
</span> </span>
<span v-if="!user.following"> <span v-if="!user.following">
<button @click="followUser" class="base05 base02-background"> <button @click="followUser" class="base05 base02-background">
Follow {{ $t('user_card.follow') }}
</button> </button>
</span> </span>
</div> </div>
<div class='mute' v-if='isOtherUser'> <div class='mute' v-if='isOtherUser'>
<span v-if='user.muted'> <span v-if='user.muted'>
<button @click="toggleMute" class="base04 base00-background pressed">Muted</button> <button @click="toggleMute" class="base04 base00-background pressed">
{{ $t('user_card.muted') }}
</button>
</span> </span>
<span v-if='!user.muted'> <span v-if='!user.muted'>
<button @click="toggleMute" class="base05 base02-background">Mute</button> <button @click="toggleMute" class="base05 base02-background">
{{ $t('user_card.mute') }}
</button>
</span> </span>
</div> </div>
</div> </div>
@ -48,18 +52,18 @@
<div class="panel-body profile-panel-body" :style="bodyStyle"> <div class="panel-body profile-panel-body" :style="bodyStyle">
<div class="user-counts"> <div class="user-counts">
<div class="user-count"> <div class="user-count">
<a href="#" v-on:click.prevent="setProfileView('statuses')" v-if="switcher"><h5 class="base05">Statuses</h5></a> <a href="#" v-on:click.prevent="setProfileView('statuses')" v-if="switcher"><h5 class="base05">{{ $t('user_card.statuses') }}</h5></a>
<h5 v-else>Statuses</h5> <h5 v-else>{{ $t('user_card.statuses') }}</h5>
<span class="base05">{{user.statuses_count}} <br><span class="dailyAvg">{{dailyAvg}} per day</span></span> <span class="base05">{{user.statuses_count}} <br><span class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span></span>
</div> </div>
<div class="user-count"> <div class="user-count">
<a href="#" v-on:click.prevent="setProfileView('friends')" v-if="switcher"><h5 class="base05">Following</h5></a> <a href="#" v-on:click.prevent="setProfileView('friends')" v-if="switcher"><h5 class="base05">{{ $t('user_card.followees') }}</h5></a>
<h5 v-else>Following</h5> <h5 v-else>{{ $t('user_card.followees') }}</h5>
<span class="base05">{{user.friends_count}}</span> <span class="base05">{{user.friends_count}}</span>
</div> </div>
<div class="user-count"> <div class="user-count">
<a href="#" v-on:click.prevent="setProfileView('followers')" v-if="switcher"><h5 class="base05">Followers</h5></a> <a href="#" v-on:click.prevent="setProfileView('followers')" v-if="switcher"><h5 class="base05">{{ $t('user_card.followers') }}</h5></a>
<h5 v-else>Followers</h5> <h5 v-else>{{ $t('user_card.followers') }}</h5>
<span class="base05">{{user.followers_count}}</span> <span class="base05">{{user.followers_count}}</span>
</div> </div>
</div> </div>

View file

@ -1,53 +1,53 @@
<template> <template>
<div class="settings panel panel-default base00-background"> <div class="settings panel panel-default base00-background">
<div class="panel-heading base01-background base04"> <div class="panel-heading base01-background base04">
User Settings {{$t('settings.user_settings')}}
</div> </div>
<div class="panel-body profile-edit"> <div class="panel-body profile-edit">
<div class="setting-item"> <div class="setting-item">
<h3>Name & Bio</h3> <h3>{{$t('settings.name_bio')}}</h3>
<p>Name</p> <p>{{$t('settings.name')}}</p>
<input class='name-changer base03-border' id='username' v-model="newname" :value="user.screen_name"></input> <input class='name-changer base03-border' id='username' v-model="newname" :value="user.screen_name"></input>
<p>Bio</p> <p>{{$t('settings.bio')}}</p>
<textarea class="bio base03-border" v-model="newbio"></textarea> <textarea class="bio base03-border" v-model="newbio"></textarea>
<button :disabled='newname.length <= 0' class="btn btn-default base05 base01-background" @click="updateProfile">Submit</button> <button :disabled='newname.length <= 0' class="btn btn-default base05 base01-background" @click="updateProfile">{{$t('general.submit')}}</button>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<h3>Avatar</h3> <h3>{{$t('settings.avatar')}}</h3>
<p>Your current avatar:</p> <p>{{$t('settings.current_avatar')}}</p>
<img :src="user.profile_image_url_original" class="old-avatar"></img> <img :src="user.profile_image_url_original" class="old-avatar"></img>
<p>Set new avatar:</p> <p>{{$t('settings.set_new_avatar')}}</p>
<img class="new-avatar" v-bind:src="previews[0]" v-if="previews[0]"> <img class="new-avatar" v-bind:src="previews[0]" v-if="previews[0]">
</img> </img>
<div> <div>
<input type="file" @change="uploadFile(0, $event)" ></input> <input type="file" @change="uploadFile(0, $event)" ></input>
</div> </div>
<i class="fa icon-spin4 animate-spin" v-if="uploading[0]"></i> <i class="fa icon-spin4 animate-spin" v-if="uploading[0]"></i>
<button class="btn btn-default base05 base01-background" v-else-if="previews[0]" @click="submitAvatar">Submit</button> <button class="btn btn-default base05 base01-background" v-else-if="previews[0]" @click="submitAvatar">{{$t('general.submit')}}</button>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<h3>Profile Banner</h3> <h3>{{$t('settings.profile_banner')}}</h3>
<p>Your current profile banner:</p> <p>{{$t('settings.current_profile_banner')}}</p>
<img :src="user.cover_photo" class="banner"></img> <img :src="user.cover_photo" class="banner"></img>
<p>Set new profile banner:</p> <p>{{$t('settings.set_new_profile_banner')}}</p>
<img class="banner" v-bind:src="previews[1]" v-if="previews[1]"> <img class="banner" v-bind:src="previews[1]" v-if="previews[1]">
</img> </img>
<div> <div>
<input type="file" @change="uploadFile(1, $event)" ></input> <input type="file" @change="uploadFile(1, $event)" ></input>
</div> </div>
<i class="fa icon-spin4 animate-spin uploading" v-if="uploading[1]"></i> <i class="fa icon-spin4 animate-spin uploading" v-if="uploading[1]"></i>
<button class="btn btn-default base05 base01-background" v-else-if="previews[1]" @click="submitBanner">Submit</button> <button class="btn btn-default base05 base01-background" v-else-if="previews[1]" @click="submitBanner">{{$t('general.submit')}}</button>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<h3>Profile Background</h3> <h3>{{$t('settings.profile_background')}}</h3>
<p>Set new profile background:</p> <p>{{$t('settings.set_new_profile_background')}}</p>
<img class="bg" v-bind:src="previews[2]" v-if="previews[2]"> <img class="bg" v-bind:src="previews[2]" v-if="previews[2]">
</img> </img>
<div> <div>
<input type="file" @change="uploadFile(2, $event)" ></input> <input type="file" @change="uploadFile(2, $event)" ></input>
</div> </div>
<i class="fa icon-spin4 animate-spin uploading" v-if="uploading[2]"></i> <i class="fa icon-spin4 animate-spin uploading" v-if="uploading[2]"></i>
<button class="btn btn-default base05 base01-background" v-else-if="previews[2]" @click="submitBg">Submit</button> <button class="btn btn-default base05 base01-background" v-else-if="previews[2]" @click="submitBg">{{$t('general.submit')}}</button>
</div> </div>
</div> </div>
</div> </div>

70
src/i18n/messages.js Normal file
View file

@ -0,0 +1,70 @@
const de = {
nav: {
timeline: 'Zeitleiste'
}
}
const en = {
nav: {
timeline: 'Timeline',
mentions: 'Mentions',
public_tl: 'Public Timeline',
twkn: 'The Whole Known Network'
},
user_card: {
follows_you: 'Follows you!',
following: 'Following!',
follow: 'Follow',
statuses: 'Statuses',
mute: 'Mute',
muted: 'Muted',
followers: 'Followers',
followees: 'Following',
per_day: 'per day'
},
timeline: {
show_new: 'Show new',
error_fetching: 'Error fetching updates',
up_to_date: 'Up-to-date',
load_older: 'Load older statuses'
},
settings: {
user_settings: 'User Settings',
name_bio: 'Name & Bio',
name: 'Name',
bio: 'Bio',
avatar: 'Avatar',
current_avatar: 'Your current avatar',
set_new_avatar: 'Set new avatar',
profile_banner: 'Profile Banner',
current_profile_banner: 'Your current profile banner',
set_new_profile_banner: 'Set new profile banner',
profile_background: 'Profile Background',
set_new_profile_background: 'Set new profile background',
settings: 'Settings',
theme: 'Theme',
filtering: 'Filtering',
filtering_explanation: 'All notices containing these words will be muted, one per line',
attachments: 'Attachments',
hide_attachments_in_tl: 'Hide attachments in timeline',
hide_attachments_in_convo: 'Hide attachments in conversations',
nsfw_clickthrough: 'Enable clickthrough NSFW attachment hiding',
autoload: 'Enable automatic loading when scrolled to the bottom',
reply_link_preview: 'Enable reply-link preview on mouse hover'
},
notifications: {
notifications: 'Notfications',
read: 'Read!',
followed_you: 'followed you'
},
general: {
submit: 'Submit'
}
}
const messages = {
de,
en
}
export default messages

View file

@ -19,9 +19,12 @@ import apiModule from './modules/api.js'
import configModule from './modules/config.js' import configModule from './modules/config.js'
import VueTimeago from 'vue-timeago' import VueTimeago from 'vue-timeago'
import VueI18n from 'vue-i18n'
import createPersistedState from './lib/persisted_state.js' import createPersistedState from './lib/persisted_state.js'
import messages from './i18n/messages.js'
Vue.use(Vuex) Vue.use(Vuex)
Vue.use(VueRouter) Vue.use(VueRouter)
Vue.use(VueTimeago, { Vue.use(VueTimeago, {
@ -30,6 +33,7 @@ Vue.use(VueTimeago, {
'en-US': require('../static/timeago.json') 'en-US': require('../static/timeago.json')
} }
}) })
Vue.use(VueI18n)
const persistedStateOptions = { const persistedStateOptions = {
paths: [ paths: [
@ -79,10 +83,17 @@ const router = new VueRouter({
} }
}) })
const i18n = new VueI18n({
locale: 'en',
fallbackLocale: 'en',
messages
})
/* eslint-disable no-new */ /* eslint-disable no-new */
new Vue({ new Vue({
router, router,
store, store,
i18n,
el: '#app', el: '#app',
render: h => h(App) render: h => h(App)
}) })

View file

@ -5696,6 +5696,10 @@ vue-hot-reload-api@^2.0.1:
version "2.0.9" version "2.0.9"
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.0.9.tgz#2e8cfbfc8e531eea57d8c1f0bd761047c7e11b56" resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.0.9.tgz#2e8cfbfc8e531eea57d8c1f0bd761047c7e11b56"
vue-i18n@^7.3.2:
version "7.3.2"
resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-7.3.2.tgz#1205bb8811323fd5c44e57e4fd619beaf2f7a9a1"
vue-loader@^11.1.0: vue-loader@^11.1.0:
version "11.1.0" version "11.1.0"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-11.1.0.tgz#8f3fcdd8a233ce96b3e99bd3d56e83cc0f2050f2" resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-11.1.0.tgz#8f3fcdd8a233ce96b3e99bd3d56e83cc0f2050f2"