From 7dd709f8a63bf55e4f57d216d22b55b7ab3d91d7 Mon Sep 17 00:00:00 2001 From: syuilo <syuilotan@yahoo.co.jp> Date: Sun, 26 Mar 2017 03:23:19 +0900 Subject: [PATCH] wip #313 --- locales/en.json | 42 ++++++++++++++++++- locales/ja.json | 42 ++++++++++++++++++- src/web/app/desktop/tags/post-form-window.tag | 8 ++-- src/web/app/desktop/tags/post-form.tag | 40 +++++++++--------- .../app/desktop/tags/ui-header-account.tag | 21 ++++++---- src/web/app/desktop/tags/ui-header-nav.tag | 6 +-- src/web/app/desktop/tags/ui-header-search.tag | 2 +- webpack.config.ts | 18 +++++++- 8 files changed, 141 insertions(+), 38 deletions(-) diff --git a/locales/en.json b/locales/en.json index 2153daa00..6d0c96fa8 100644 --- a/locales/en.json +++ b/locales/en.json @@ -29,7 +29,47 @@ "desktop": { "tags": { "mk-ui-header-nav": { - "home": "Home" + "home": "Home", + "messaging": "Messaging", + "info": "Info", + "live": "Live" + }, + "mk-ui-header-search": { + "placeholder": "Search" + }, + "mk-ui-header-account": { + "profile": "Your profile", + "drive": "Drive", + "mentions": "Mentions", + "settings": "Settings", + "signout": "Sign out" + }, + "mk-post-form": { + "post-placeholder": "What's happening?", + "reply-placeholder": "この投稿への返信...", + "quote-placeholder": "この投稿を引用...", + "post": "Post", + "reply": "Reply", + "repost": "Repost", + "posted": "Posted!", + "replied": "Replied!", + "reposted": "Reposted!", + "post-failed": "Failed to post", + "reply-failed": "Failed to reply", + "repost-failed": "Failed to repost", + "posting": "Posting", + "attach-media-from-local": "Attach media from your pc", + "attach-media-from-drive": "Attach media from the drive", + "attach-cancel": "Cancel to attach", + "insert-the-cat": "Insert the cat", + "create-poll": "Create a poll", + "text-remain": "{} characters remaining" + }, + "mk-post-form-window": { + "post": "New post", + "reply": "Reply", + "attaches": "{} media attached", + "uploading-media": "{} media uploading" } } } diff --git a/locales/ja.json b/locales/ja.json index 4131af960..dbe11f5e8 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -29,7 +29,47 @@ "desktop": { "tags": { "mk-ui-header-nav": { - "home": "ホーム" + "home": "ホーム", + "messaging": "メッセージ", + "info": "お知らせ", + "live": "ライブ" + }, + "mk-ui-header-search": { + "placeholder": "検索" + }, + "mk-ui-header-account": { + "profile": "プロフィール", + "drive": "ドライブ", + "mentions": "あなた宛て", + "settings": "設定", + "signout": "サインアウト" + }, + "mk-post-form": { + "post-placeholder": "いまどうしてる?", + "reply-placeholder": "この投稿への返信...", + "quote-placeholder": "この投稿を引用...", + "post": "投稿", + "reply": "返信", + "repost": "Repost", + "posted": "投稿しました!", + "replied": "返信しました!", + "reposted": "Repostしました!", + "post-failed": "投稿できませんでした", + "reply-failed": "返信できませんでした", + "repost-failed": "Repostできませんでした", + "posting": "投稿中", + "attach-media-from-local": "PCからメディアを添付", + "attach-media-from-drive": "ドライブからメディアを添付", + "attach-cancel": "添付取り消し", + "insert-the-cat": "猫挿入", + "create-poll": "投票を作成", + "text-remain": "のこり{}文字" + }, + "mk-post-form-window": { + "post": "新規投稿", + "reply": "返信", + "attaches": "添付: {}メディア", + "uploading-media": "{}つのメディアをアップロード中" } } } diff --git a/src/web/app/desktop/tags/post-form-window.tag b/src/web/app/desktop/tags/post-form-window.tag index adc70a93f..745aa64c8 100644 --- a/src/web/app/desktop/tags/post-form-window.tag +++ b/src/web/app/desktop/tags/post-form-window.tag @@ -1,10 +1,10 @@ <mk-post-form-window> <mk-window ref="window" is-modal={ true }> <yield to="header"> - <span if={ !parent.opts.reply }>新規投稿</span> - <span if={ parent.opts.reply }>返信</span> - <span class="files" if={ parent.files.length != 0 }>添付: { parent.files.length }ファイル</span> - <span class="uploading-files" if={ parent.uploadingFiles.length != 0 }>{ parent.uploadingFiles.length }個のファイルをアップロード中<mk-ellipsis></mk-ellipsis></span> + <span if={ !parent.opts.reply }>%i18n:desktop.tags.mk-post-form-window.post%</span> + <span if={ parent.opts.reply }>%i18n:desktop.tags.mk-post-form-window.reply%</span> + <span class="files" if={ parent.files.length != 0 }>{ '%i18n:desktop.tags.mk-post-form-window.attaches%'.replace('{}', parent.files.length) }</span> + <span class="uploading-files" if={ parent.uploadingFiles.length != 0 }>{ '%i18n:desktop.tags.mk-post-form-window.uploading-media%'.replace('{}', parent.uploadingFiles.length) }<mk-ellipsis></mk-ellipsis></span> </yield> <yield to="content"> <div class="ref" if={ parent.opts.reply }> diff --git a/src/web/app/desktop/tags/post-form.tag b/src/web/app/desktop/tags/post-form.tag index 1f6303bcb..ca6b5eb9d 100644 --- a/src/web/app/desktop/tags/post-form.tag +++ b/src/web/app/desktop/tags/post-form.tag @@ -5,22 +5,22 @@ <ul> <li each={ files }> <div class="img" style="background-image: url({ url + '?thumbnail&size=64' })" title={ name }></div> - <img class="remove" onclick={ removeFile } src="/assets/desktop/remove.png" title="添付取り消し" alt=""/> + <img class="remove" onclick={ removeFile } src="/assets/desktop/remove.png" title="%i18n:desktop.tags.mk-post-form.attach-cancel%" alt=""/> </li> - <li class="add" if={ files.length < 4 } title="PCからファイルを添付" onclick={ selectFile }><i class="fa fa-plus"></i></li> + <li class="add" if={ files.length < 4 } title="%i18n:desktop.tags.mk-post-form.attach-media-from-local%" onclick={ selectFile }><i class="fa fa-plus"></i></li> </ul> <p class="remain">{ 4 - files.length }/4</p> </div> <mk-poll-editor if={ poll } ref="poll" ondestroy={ onPollDestroyed }></mk-poll-editor> </div> <mk-uploader ref="uploader"></mk-uploader> - <button ref="upload" title="PCからファイルを添付" onclick={ selectFile }><i class="fa fa-upload"></i></button> - <button ref="drive" title="ドライブからファイルを添付" onclick={ selectFileFromDrive }><i class="fa fa-cloud"></i></button> - <button class="cat" title="Insert The Cat" onclick={ cat }><i class="fa fa-smile-o"></i></button> - <button class="poll" title="投票を作成" onclick={ addPoll }><i class="fa fa-pie-chart"></i></button> - <p class="text-count { over: refs.text.value.length > 1000 }">のこり{ 1000 - refs.text.value.length }文字</p> + <button ref="upload" title="%i18n:desktop.tags.mk-post-form.attach-media-from-local%" onclick={ selectFile }><i class="fa fa-upload"></i></button> + <button ref="drive" title="%i18n:desktop.tags.mk-post-form.attach-media-from-drive%" onclick={ selectFileFromDrive }><i class="fa fa-cloud"></i></button> + <button class="cat" title="%i18n:desktop.tags.mk-post-form.insert-the-cat%" onclick={ cat }><i class="fa fa-smile-o"></i></button> + <button class="poll" title="%i18n:desktop.tags.mk-post-form.create-poll%" onclick={ addPoll }><i class="fa fa-pie-chart"></i></button> + <p class="text-count { over: refs.text.value.length > 1000 }">{ '%i18n:desktop.tags.mk-post-form.text-remain%'.replace('{}', 1000 - refs.text.value.length) }</p> <button class={ wait: wait } ref="submit" disabled={ wait || (refs.text.value.length == 0 && files.length == 0 && !poll && !repost) } onclick={ post }> - { wait ? '投稿中' : submitText }<mk-ellipsis if={ wait }></mk-ellipsis> + { wait ? '%i18n:desktop.tags.mk-post-form.posting%' : submitText }<mk-ellipsis if={ wait }></mk-ellipsis> </button> <input ref="file" type="file" accept="image/*" multiple="multiple" tabindex="-1" onchange={ changeFile }/> <div class="dropzone" if={ draghover }></div> @@ -329,16 +329,16 @@ if (this.repost == '') this.repost = null; this.placeholder = this.repost - ? 'この投稿を引用...' + ? '%i18n:desktop.tags.mk-post-form.quote-placeholder%' : this.inReplyToPost - ? 'この投稿への返信...' - : 'いまどうしてる?'; + ? '%i18n:desktop.tags.mk-post-form.reply-placeholder%' + : '%i18n:desktop.tags.mk-post-form.post-placeholder%'; this.submitText = this.repost - ? 'Repost' + ? '%i18n:desktop.tags.mk-post-form.repost%' : this.inReplyToPost - ? '返信' - : '投稿'; + ? '%i18n:desktop.tags.mk-post-form.reply%' + : '%i18n:desktop.tags.mk-post-form.post%'; this.draftId = this.repost ? 'repost:' + this.repost.id @@ -489,16 +489,16 @@ this.removeDraft(); this.trigger('post'); notify(this.repost - ? 'Repostしました!' + ? '%i18n:desktop.tags.mk-post-form.reposted%' : this.inReplyToPost - ? '返信しました!' - : '投稿しました!'); + ? '%i18n:desktop.tags.mk-post-form.replied%' + : '%i18n:desktop.tags.mk-post-form.posted%'); }).catch(err => { notify(this.repost - ? 'Repostできませんでした' + ? '%i18n:desktop.tags.mk-post-form.repost-failed%' : this.inReplyToPost - ? '返信できませんでした' - : '投稿できませんでした'); + ? '%i18n:desktop.tags.mk-post-form.reply-failed%' + : '%i18n:desktop.tags.mk-post-form.post-failed%'); }).then(() => { this.update({ wait: false diff --git a/src/web/app/desktop/tags/ui-header-account.tag b/src/web/app/desktop/tags/ui-header-account.tag index e47572edb..a8f83ad00 100644 --- a/src/web/app/desktop/tags/ui-header-account.tag +++ b/src/web/app/desktop/tags/ui-header-account.tag @@ -1,21 +1,28 @@ <mk-ui-header-account> - <button class="header" data-active={ isOpen.toString() } onclick={ toggle }><span class="username">{ I.username }<i class="fa fa-angle-down" if={ !isOpen }></i><i class="fa fa-angle-up" if={ isOpen }></i></span><img class="avatar" src={ I.avatar_url + '?thumbnail&size=64' } alt="avatar"/></button> + <button class="header" data-active={ isOpen.toString() } onclick={ toggle }> + <span class="username">{ I.username }<i class="fa fa-angle-down" if={ !isOpen }></i><i class="fa fa-angle-up" if={ isOpen }></i></span> + <img class="avatar" src={ I.avatar_url + '?thumbnail&size=64' } alt="avatar"/> + </button> <div class="menu" if={ isOpen }> <ul> - <li><a href={ '/' + I.username }><i class="fa fa-user"></i>プロフィール<i class="fa fa-angle-right"></i></a></li> - <li onclick={ drive }> - <p><i class="fa fa-cloud"></i>ドライブ<i class="fa fa-angle-right"></i></p> + <li> + <a href={ '/' + I.username }><i class="fa fa-user"></i>%i18n:desktop.tags.mk-ui-header-account.profile%<i class="fa fa-angle-right"></i></a> + </li> + <li onclick={ drive }> + <p><i class="fa fa-cloud"></i>%i18n:desktop.tags.mk-ui-header-account.drive%<i class="fa fa-angle-right"></i></p> + </li> + <li> + <a href="/i>mentions"><i class="fa fa-at"></i>%i18n:desktop.tags.mk-ui-header-account.mentions%<i class="fa fa-angle-right"></i></a> </li> - <li><a href="/i>mentions"><i class="fa fa-at"></i>あなた宛て<i class="fa fa-angle-right"></i></a></li> </ul> <ul> <li onclick={ settings }> - <p><i class="fa fa-cog"></i>設定<i class="fa fa-angle-right"></i></p> + <p><i class="fa fa-cog"></i>%i18n:desktop.tags.mk-ui-header-account.settings%<i class="fa fa-angle-right"></i></p> </li> </ul> <ul> <li onclick={ signout }> - <p><i class="fa fa-power-off"></i>サインアウト<i class="fa fa-angle-right"></i></p> + <p><i class="fa fa-power-off"></i>%i18n:desktop.tags.mk-ui-header-account.signout%<i class="fa fa-angle-right"></i></p> </li> </ul> </div> diff --git a/src/web/app/desktop/tags/ui-header-nav.tag b/src/web/app/desktop/tags/ui-header-nav.tag index 2fb0f8c51..80352dc12 100644 --- a/src/web/app/desktop/tags/ui-header-nav.tag +++ b/src/web/app/desktop/tags/ui-header-nav.tag @@ -9,20 +9,20 @@ <li class="messaging"> <a onclick={ messaging }> <i class="fa fa-comments"></i> - <p>メッセージ</p> + <p>%i18n:desktop.tags.mk-ui-header-nav.messaging%</p> <i class="fa fa-circle" if={ hasUnreadMessagingMessages }></i> </a> </li> <li class="info"> <a href="https://twitter.com/misskey_xyz" target="_blank"> <i class="fa fa-info"></i> - <p>お知らせ</p> + <p>%i18n:desktop.tags.mk-ui-header-nav.info%</p> </a> </li> <li class="live"> <a href="https://misskey.tk" target="_blank"> <i class="fa fa-television"></i> - <p>ライブ</p> + <p>%i18n:desktop.tags.mk-ui-header-nav.live%</p> </a> </li> </ul> diff --git a/src/web/app/desktop/tags/ui-header-search.tag b/src/web/app/desktop/tags/ui-header-search.tag index ff1a313ce..616476f42 100644 --- a/src/web/app/desktop/tags/ui-header-search.tag +++ b/src/web/app/desktop/tags/ui-header-search.tag @@ -1,6 +1,6 @@ <mk-ui-header-search> <form class="search" onsubmit={ onsubmit }> - <input ref="q" type="search" placeholder=" 検索"/> + <input ref="q" type="search" placeholder=" %i18n:desktop.tags.mk-ui-header-search.placeholder%"/> <div class="result"></div> </form> <style> diff --git a/webpack.config.ts b/webpack.config.ts index b67c0e903..b501eb1ef 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -33,7 +33,23 @@ module.exports = (Object as any).entries(languages).map(([lang, locale]) => { exclude: /node_modules/, loader: StringReplacePlugin.replace({ replacements: [ - { pattern: /%i18n:(.+?)%/g, replacement: (_, text) => eval('locale' + text.split('.').map(x => `['${x}']`).join('')) } + { pattern: /%i18n:(.+?)%/g, replacement: (_, key) => { + let text = locale; + const error = key.split('.').some(k => { + if (text.hasOwnProperty(k)) { + text = text[k]; + return false; + } else { + return true; + } + }); + if (error) { + console.warn(`key '${key}' not found in '${lang}'`); + return '-UNTRANSLATED-'; + } else { + return text.replace(/'/g, '\\\'').replace(/"/g, '\\"'); + } + } } ] }) },