{{ title }}
+{{ description }}
+ +$2
'); + +export { + license, + licenseHtml +}; diff --git a/src/cafy-id.ts b/src/cafy-id.ts new file mode 100644 index 000000000..310b1eb20 --- /dev/null +++ b/src/cafy-id.ts @@ -0,0 +1,29 @@ +import * as mongo from 'mongodb'; +import { Query } from 'cafy'; + +export const isAnId = x => mongo.ObjectID.isValid(x); +export const isNotAnId = x => !isAnId(x); + +/** + * ID + */ +export default class ID extends Query{{ app.nameId }}
+{{ app.description }}
+読み込み中
このアプリがあなたのアカウントにアクセスすることはありません。
+アプリケーションに戻っています
アプリケーションに戻って、やっていってください。
+セッションが存在しません。
+このチャンネルをウォッチしています ウォッチ解除
- +このチャンネルをウォッチしています ウォッチ解除
+読み込み中
まだ投稿がありません
-読み込み中
まだ投稿がありません
+ +参加するにはログインまたは新規登録してください
>>{ reply.index } ({ reply.user.name }): [x]
+>>{ reply.index } ({ getUserName(reply.user) }): [x]
+
+ %fa:check%
+ %fa:times%
+
+ {{ network == null ? '%i18n:!@checking-network%' : '%i18n:!@network%' }}
+
+ %fa:check%
+ %fa:times%
+
+ {{ internet == null ? '%i18n:!@checking-internet%' : '%i18n:!@internet%' }}
+
+ %fa:check%
+ %fa:times%
+
+ {{ server == null ? '%i18n:!@checking-server%' : '%i18n:!@server%' }}
%i18n:@finding%
%fa:exclamation-triangle%%i18n:@no-network%
%i18n:@no-network-desc%
%fa:exclamation-triangle%%i18n:@no-internet%
%i18n:@no-internet-desc%
%fa:exclamation-triangle%%i18n:@no-server%
%i18n:@no-server-desc%
%fa:info-circle%%i18n:@success%
%i18n:@success-desc%
+ {{ '%i18n:!@description%'.substr(0, '%i18n:!@description%'.indexOf('{')) }} + {{ '%i18n:!@description%'.match(/\{(.+?)\}/)[1] }} + {{ '%i18n:!@description%'.substr('%i18n:!@description%'.indexOf('}') + 1) }} +
+%i18n:@thanks%
+%fa:spinner .spin%%i18n:common.loading%
+%fa:info-circle%%i18n:@empty%
+%fa:flag%%i18n:@no-history%
++ {{ _messages[i + 1]._datetext }} +
+ +%i18n:@no-history%
+%fa:spinner .pulse .fw%%i18n:common.loading%
{{ logPos }}ターン目 黒:{{ o.blackCount }} 白:{{ o.whiteCount }} 合計:{{ o.blackCount + o.whiteCount }}
+ +ゲームの設定
+ +他のMisskeyユーザーとオセロで対戦しよう
+オセロは、相手と交互に石をボードに置いてゆき、相手の石を挟んでひっくり返しながら、最終的に残った石が多い方が勝ちというボードゲームです。
++ %fa:exclamation-triangle%%i18n:@no-only-one-choice% +
++ {{ '%i18n:!@total-users%'.replace('{}', total) }} + ・ + {{ showResult ? '%i18n:!@vote%' : '%i18n:!@show-result%' }} + %i18n:@voted% +
+{{ title }}
+
+ %fa:spinner .pulse%
+ %i18n:@connecting%
+ %fa:spinner .pulse%
+ %i18n:@reconnecting%
+ %fa:check% + %i18n:@connected% +
+
+
%i18n:@description%%i18n:@detail%
+%i18n:@connected-to%: @{{ os.i.twitter.screenName }}
++ {{ os.i.twitter ? '%i18n:!@reconnect%' : '%i18n:!@connect%' }} + or + %i18n:@disconnect% +
+Twitter ID: {{ os.i.twitter.userId }}
+%fa:spinner .pulse%{{ ctx.name }}
+
+ %i18n:@waiting%
+ {{ req.ip }} + {{ req.method }} + {{ req.path }} +
+%i18n:@fetching%
+ + %i18n:@have-a-nice-day% +
+ %i18n:@next% >> ++ {{ year }}年 + {{ month }}月 +
+{{ day }}日
+{{ weekDay }}曜日
+今日:{{ dayP.toFixed(1) }}%
+今月:{{ monthP.toFixed(1) }}%
+今年:{{ yearP.toFixed(1) }}%
++ {{ '%i18n:!@text%'.substr(0, '%i18n:!@text%'.indexOf('{')) }} + @syuilo + {{ '%i18n:!@text%'.substr('%i18n:!@text%'.indexOf('}') + 1) }} +
+%fa:spinner .pulse .fw%%i18n:common.loading%
%i18n:@no-photos%
+%fa:spinner .pulse .fw%%i18n:common.loading%
%fa:microchip%CPU
+{{ meta.cpu.cores }} Cores
+{{ meta.cpu.model }}
+%fa:R hdd%Storage
+Total: {{ total | bytes(1) }}
+Available: {{ available | bytes(1) }}
+Used: {{ used | bytes(1) }}
+%fa:flask%Memory
+Total: {{ total | bytes(1) }}
+Used: {{ used | bytes(1) }}
+Free: {{ free | bytes(1) }}
+Uptimes
+Process: {{ process ? process.toFixed(0) : '---' }}s
+OS: {{ os ? os.toFixed(0) : '---' }}s
+%fa:spinner .pulse .fw%%i18n:common.loading%
%fa:R lightbulb%
+ver {{ version }} ({{ codename }})
+ + + + + diff --git a/src/client/app/config.ts b/src/client/app/config.ts new file mode 100644 index 000000000..522d7ff05 --- /dev/null +++ b/src/client/app/config.ts @@ -0,0 +1,37 @@ +declare const _HOST_: string; +declare const _HOSTNAME_: string; +declare const _URL_: string; +declare const _API_URL_: string; +declare const _WS_URL_: string; +declare const _DOCS_URL_: string; +declare const _STATS_URL_: string; +declare const _STATUS_URL_: string; +declare const _DEV_URL_: string; +declare const _LANG_: string; +declare const _RECAPTCHA_SITEKEY_: string; +declare const _SW_PUBLICKEY_: string; +declare const _THEME_COLOR_: string; +declare const _COPYRIGHT_: string; +declare const _VERSION_: string; +declare const _CODENAME_: string; +declare const _LICENSE_: string; +declare const _GOOGLE_MAPS_API_KEY_: string; + +export const host = _HOST_; +export const hostname = _HOSTNAME_; +export const url = _URL_; +export const apiUrl = _API_URL_; +export const wsUrl = _WS_URL_; +export const docsUrl = _DOCS_URL_; +export const statsUrl = _STATS_URL_; +export const statusUrl = _STATUS_URL_; +export const devUrl = _DEV_URL_; +export const lang = _LANG_; +export const recaptchaSitekey = _RECAPTCHA_SITEKEY_; +export const swPublickey = _SW_PUBLICKEY_; +export const themeColor = _THEME_COLOR_; +export const copyright = _COPYRIGHT_; +export const version = _VERSION_; +export const codename = _CODENAME_; +export const license = _LICENSE_; +export const googleMapsApiKey = _GOOGLE_MAPS_API_KEY_; diff --git a/src/client/app/desktop/api/choose-drive-file.ts b/src/client/app/desktop/api/choose-drive-file.ts new file mode 100644 index 000000000..fbda600e6 --- /dev/null +++ b/src/client/app/desktop/api/choose-drive-file.ts @@ -0,0 +1,30 @@ +import { url } from '../../config'; +import MkChooseFileFromDriveWindow from '../views/components/choose-file-from-drive-window.vue'; + +export default function(opts) { + return new Promise((res, rej) => { + const o = opts || {}; + + if (document.body.clientWidth > 800) { + const w = new MkChooseFileFromDriveWindow({ + propsData: { + title: o.title, + multiple: o.multiple, + initFolder: o.currentFolder + } + }).$mount(); + w.$once('selected', file => { + res(file); + }); + document.body.appendChild(w.$el); + } else { + window['cb'] = file => { + res(file); + }; + + window.open(url + '/selectdrive', + 'choose_drive_window', + 'height=500, width=800'); + } + }); +} diff --git a/src/client/app/desktop/api/choose-drive-folder.ts b/src/client/app/desktop/api/choose-drive-folder.ts new file mode 100644 index 000000000..9b33a20d9 --- /dev/null +++ b/src/client/app/desktop/api/choose-drive-folder.ts @@ -0,0 +1,17 @@ +import MkChooseFolderFromDriveWindow from '../views/components/choose-folder-from-drive-window.vue'; + +export default function(opts) { + return new Promise((res, rej) => { + const o = opts || {}; + const w = new MkChooseFolderFromDriveWindow({ + propsData: { + title: o.title, + initFolder: o.currentFolder + } + }).$mount(); + w.$once('selected', folder => { + res(folder); + }); + document.body.appendChild(w.$el); + }); +} diff --git a/src/client/app/desktop/api/contextmenu.ts b/src/client/app/desktop/api/contextmenu.ts new file mode 100644 index 000000000..b70d7122d --- /dev/null +++ b/src/client/app/desktop/api/contextmenu.ts @@ -0,0 +1,16 @@ +import Ctx from '../views/components/context-menu.vue'; + +export default function(e, menu, opts?) { + const o = opts || {}; + const vm = new Ctx({ + propsData: { + menu, + x: e.pageX - window.pageXOffset, + y: e.pageY - window.pageYOffset, + } + }).$mount(); + vm.$once('closed', () => { + if (o.closed) o.closed(); + }); + document.body.appendChild(vm.$el); +} diff --git a/src/client/app/desktop/api/dialog.ts b/src/client/app/desktop/api/dialog.ts new file mode 100644 index 000000000..07935485b --- /dev/null +++ b/src/client/app/desktop/api/dialog.ts @@ -0,0 +1,19 @@ +import Dialog from '../views/components/dialog.vue'; + +export default function(opts) { + return new Promise%fa:spinner .pulse .fw%%i18n:common.loading%
{{ '%i18n:!@title%'.replace('{1}', year).replace('{2}', month) }}
+{{ usage.toFixed(1) }}% %i18n:@used%
+ %fa:cloud%%i18n:@drive% + +%i18n:@avatar%
+%i18n:@banner%
++ {{ file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name }} + {{ file.name.substr(file.name.lastIndexOf('.')) }} +
++ %fa:R folder-open .fw% + %fa:R folder .fw% + {{ folder.name }} +
+%i18n:@empty-draghover%
+%i18n:@empty-drive%
%i18n:@empty-drive-description%
%i18n:@empty-folder%
+気になるユーザーをフォロー:
+@{{ user | acct }}
+おすすめのユーザーは見つかりませんでした。
+%fa:spinner .pulse .fw%読み込んでいます
ウィジェットを追加:
+ +ゴミ箱
++ %fa:R comments% + あなた宛ての投稿はありません。 + あなたがフォローしているユーザーからの言及はありません。 +
+
+
+ {{ p.cw }} + {{ showContent ? '隠す' : 'もっと見る' }} +
+ +読み込みに失敗しました。
++ %fa:angle-up%{{ note._datetext }} + %fa:angle-down%{{ _notes[i + 1]._datetext }} +
+ +
+
%fa:retweet%
+
%fa:quote-left%
+
%fa:user-plus%
+
%fa:reply%
+
%fa:at%
+
%fa:chart-pie%{{ notification.user | userName }}
++ %fa:angle-up%{{ notification._datetext }} + %fa:angle-down%{{ _notifications[i + 1]._datetext }} +
+ +%i18n:@empty%
+%fa:spinner .pulse .fw%%i18n:common.loading%
{{ 1000 - text.length }}
+待機中
{{ Math.floor((value / max) * 100) }}
+ + +%i18n:@intro%%i18n:@detail%
+%fa:exclamation-triangle%%i18n:@caution%
%i18n:@already-registered%
+%fa:info-circle%%i18n:@info%
Token: {{ os.i.token }}
%i18n:@intro%
+%fa:exclamation-triangle%%i18n:@caution%
%i18n:@regeneration-of-token%
+%fa:info-circle%%i18n:@no-apps%
+{{ app.name }}
+{{ app.description }}
+{{ capacity | bytes }}中{{ usage | bytes }}使用中
+ +%fa:info-circle%%i18n:@no-users%
+{{ user | userName }} @{{ user | acct }}
+%fa:info-circle%変更はページの再度読み込み後に反映されます。
+%fa:exclamation-triangle%クリーンアップを行うと、ブラウザに記憶されたアカウント情報のキャッシュ、書きかけの投稿・返信・メッセージ、およびその他のデータ(設定情報含む)が削除されます。クリーンアップを行った後はページを再度読み込みする必要があります。
+このサーバーの運営者: {{ meta.maintainer.name }}
+
+ バージョン: {{ version }}
+
+
+ 最新のバージョン: {{ latestVersion ? latestVersion : version }}
+
+
%fa:info-circle%Misskeyはソースマップも提供しています。
+{{ props.row.data }}+
{{ props.row.res }}+ +
{{ props.row.data }}+ +
+ %fa:R comments%%i18n:@empty% +
+{{ message }}
+おかえりなさい、{{ os.i | userName }}さん
+@{{ u | acct }}
+フォローされています
+
+
%fa:spinner .pulse .fw%読み込んでいます
%fa:search%「{{ q }}」に関する投稿は見つかりませんでした。
+%fa:spinner .pulse .fw% %i18n:common.loading%
@{{ _user | acct }}
+%i18n:@no-one%
+%fa:users%%i18n:@title%
+%fa:spinner .pulse .fw%%i18n:@loading%
%i18n:@no-users%
+%fa:users%%i18n:@title%
+%fa:spinner .pulse .fw%%i18n:@loading%
@{{ friend | acct }}
+%i18n:@no-users%
+%fa:exclamation-triangle% %i18n:@is-suspended%
%fa:exclamation-triangle% %i18n:@is-remote%%i18n:@view-remote%
{{ user | userName }}
+@{{ user | acct }}
+%fa:map-marker%{{ user.profile.location }}
+%i18n:@last-used-at%:
%fa:camera%%i18n:@title%
+%fa:spinner .pulse .fw%%i18n:@loading%
%i18n:@no-photos%
+%i18n:@follows-you%
++ %i18n:@stalking% %fa:meh% %i18n:@unstalk% + %fa:user-secret% %i18n:@stalk% +
+%fa:birthday-cake%{{ user.profile.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ age }}歳)
+%fa:B twitter%@{{ user.twitter.screenName }}
+%fa:angle-right%{{ user.notesCount }}投稿
+%fa:angle-right%{{ user.followingCount }}人をフォロー
+%fa:angle-right%{{ user.followersCount }}人のフォロワー
+%fa:R comments%このユーザーはまだ何も投稿していないようです。
+ようこそ! MisskeyはTwitter風ミニブログSNSです。思ったことや皆と共有したいことを投稿しましょう。タイムラインを見れば、皆の関心事をすぐにチェックすることもできます。詳しく...
+読み込み中
まだ投稿がありません
+%fa:tv%{{ channel ? channel.title : '%i18n:!@title%' }}
+%i18n:@get-started%
+%i18n:@nothing%
+%fa:spinner .pulse .fw%%i18n:common.loading%
%fa:pencil-alt%%i18n:@title%
+ + +@{{ os.i | acct }}
+%fa:spinner .pulse .fw%%i18n:common.loading%
%i18n:@nothing%
+%fa:spinner .pulse .fw%%i18n:common.loading%
@{{ _user | acct }}
+%i18n:@no-one%
+読み込み中
+読み込み中
+ +%fa:spinner .pulse .fw%確認しています...
+%fa:fw check%利用できます
+%fa:fw exclamation-triangle%既に利用されています
+%fa:fw exclamation-triangle%通信エラー
+%fa:fw exclamation-triangle%a~z、A~Z、0~9、_が使えます
+%fa:fw exclamation-triangle%1文字以上でお願いします!
+%fa:fw exclamation-triangle%30文字以内でお願いします
+お使いのブラウザ(またはOS)のバージョンを更新すると解決する可能性があります。
' + + 'エラーコード: ${e.toString()}
` + + `ブラウザ バージョン: ${navigator.userAgent}
` + + `クライアント バージョン: ${version}
` + + '問題が解決しない場合は、上記の情報をお書き添えの上 syuilotan@yahoo.co.jp までご連絡ください。
' + + 'Thank you for using Misskey.
' + + '+ %fa:camera%%i18n:@exif% +
+{{ exif ? JSON.stringify(exif, null, 2) : '' }}+
+ %fa:hashtag%%i18n:@hash% +
+{{ file.md5 }}
+ + {{ file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name }} + {{ file.name.substr(file.name.lastIndexOf('.')) }} +
+ + +%fa:folder%{{ folder.name }}
%fa:angle-right% +{{ (info.usage / info.capacity * 100).toFixed(1) }}% %i18n:@used%
++ {{ folder.foldersCount }} %i18n:@folder-count% + %i18n:@count-separator% + {{ folder.filesCount }} %i18n:@file-count% +
+%i18n:@load-more%
+%i18n:@nothing-in-drive%
+%i18n:@folder-is-empty%
+気になるユーザーをフォロー:
+おすすめのユーザーは見つかりませんでした。
+%fa:spinner .pulse .fw%読み込んでいます
+
+ {{ p.cw }} + {{ showContent ? '隠す' : 'もっと見る' }} +
+ + via {{ p.app.name }} +読み込みに失敗しました。
++ %fa:angle-up%{{ note._datetext }} + %fa:angle-down%{{ _notes[i + 1]._datetext }} +
+ +%fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%
+%fa:retweet%{{ notification.note.user | userName }}
+%fa:quote-left%{{ getNoteSummary(notification.note.renote) }}%fa:quote-right%
+%fa:quote-left%{{ notification.note.user | userName }}
+{{ getNoteSummary(notification.note) }}
+%fa:user-plus%{{ notification.user | userName }}
+%fa:reply%{{ notification.note.user | userName }}
+{{ getNoteSummary(notification.note) }}
+%fa:at%{{ notification.note.user | userName }}
+{{ getNoteSummary(notification.note) }}
+%fa:chart-pie%{{ notification.user | userName }}
+%fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%
++ %fa:angle-up%{{ notification._datetext }} + %fa:angle-down%{{ _notifications[i + 1]._datetext }} +
+ +%i18n:@empty%
+%fa:spinner .pulse .fw%%i18n:common.loading%
おかえりなさい、{{ os.i | userName }}さん
+
+
%fa:spinner .pulse .fw%%i18n:common.loading%
%fa:info-circle%%i18n:@will-be-published%
+ver {{ version }} ({{ codename }})
+いつでも、どこからでもMisskeyを利用できます。もちろん、無料です。
+新規登録
+%fa:exclamation-triangle% %i18n:@is-suspended%
%fa:exclamation-triangle% %i18n:@is-remote%%i18n:@view-remote%
+ %fa:map-marker%{{ user.profile.location }} +
++ %fa:birthday-cake%{{ user.profile.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ age }}歳) +
+%fa:spinner .pulse .fw%%i18n:@loading%
%i18n:@no-users%
+%fa:spinner .pulse .fw%%i18n:@loading%
%i18n:@no-notes%
+%i18n:@last-used-at%:
Twitter風ミニブログSNS、Misskeyへようこそ。共有したいことを投稿したり、タイムラインでみんなの投稿を読むこともできます。
アカウントを作成する
%fa:lock% ログイン
+%fa:comments R% タイムラインを見てみる
+