diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2020-03-29 17:46:31 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2020-03-29 17:46:31 +0900 |
| commit | cc66a1f9c7733f0ff3c23b60a8578cdb1235a3f2 (patch) | |
| tree | e7e7697fcfc2ec63c642e5496030bdd46f87601b /src | |
| parent | Merge branch 'develop' (diff) | |
| parent | 12.28.0 (diff) | |
| download | sharkey-cc66a1f9c7733f0ff3c23b60a8578cdb1235a3f2.tar.gz sharkey-cc66a1f9c7733f0ff3c23b60a8578cdb1235a3f2.tar.bz2 sharkey-cc66a1f9c7733f0ff3c23b60a8578cdb1235a3f2.zip | |
Merge branch 'develop'
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/app.vue | 4 | ||||
| -rw-r--r-- | src/client/components/date-separated-list.vue | 4 | ||||
| -rw-r--r-- | src/client/pages/apps.vue | 6 | ||||
| -rw-r--r-- | src/client/pages/instance/federation.vue | 32 | ||||
| -rw-r--r-- | src/client/pages/instance/queue.vue | 3 | ||||
| -rw-r--r-- | src/client/pages/messaging/messaging-room.vue | 2 | ||||
| -rw-r--r-- | src/client/pages/miauth.vue | 6 | ||||
| -rw-r--r-- | src/client/theme.ts | 26 | ||||
| -rw-r--r-- | src/client/widgets/memo.vue | 17 | ||||
| -rw-r--r-- | src/db/postgre.ts | 6 | ||||
| -rw-r--r-- | src/docs/theme.ja-JP.md | 74 | ||||
| -rw-r--r-- | src/models/repositories/notification.ts | 4 | ||||
| -rw-r--r-- | src/server/api/define.ts | 6 | ||||
| -rw-r--r-- | src/server/api/endpoints/i/apps.ts | 1 | ||||
| -rw-r--r-- | src/server/api/endpoints/meta.ts | 1 | ||||
| -rw-r--r-- | src/server/api/endpoints/notifications/create.ts | 2 | ||||
| -rw-r--r-- | src/server/api/stream/index.ts | 4 |
17 files changed, 154 insertions, 44 deletions
diff --git a/src/client/app.vue b/src/client/app.vue index 99268e42bf..fc40b6973a 100644 --- a/src/client/app.vue +++ b/src/client/app.vue @@ -975,6 +975,10 @@ export default Vue.extend({ &:not(.naked) { background: var(--pageBg); } + + &.naked { + background: var(--bg); + } } } diff --git a/src/client/components/date-separated-list.vue b/src/client/components/date-separated-list.vue index d41dd9d521..b80c6494ed 100644 --- a/src/client/components/date-separated-list.vue +++ b/src/client/components/date-separated-list.vue @@ -1,8 +1,8 @@ <template> <component :is="$store.state.device.animation ? 'transition-group' : 'div'" class="sqadhkmv" name="list" tag="div" :data-direction="direction" :data-reversed="reversed ? 'true' : 'false'"> <template v-for="(item, i) in items"> - <slot :item="item" :i="i"></slot> - <div class="separator" :key="item.id + '_date'" v-if="showDate(i, item)"> + <slot :item="item"></slot> + <div class="separator" v-if="showDate(i, item)" :key="item.id + '_date'"> <p class="date"> <span><fa class="icon" :icon="faAngleUp"/>{{ getDateText(item.createdAt) }}</span> <span>{{ getDateText(items[i + 1].createdAt) }}<fa class="icon" :icon="faAngleDown"/></span> diff --git a/src/client/pages/apps.vue b/src/client/pages/apps.vue index 03c6707f95..445bba34c8 100644 --- a/src/client/pages/apps.vue +++ b/src/client/pages/apps.vue @@ -27,6 +27,12 @@ <div class="actions"> <button class="_button" @click="revoke(token)"><fa :icon="faTrashAlt"/></button> </div> + <details> + <summary>{{ $t('details') }}</summary> + <ul> + <li v-for="p in token.permission" :key="p">{{ $t(`_permissions.${p}`) }}</li> + </ul> + </details> </div> </div> </template> diff --git a/src/client/pages/instance/federation.vue b/src/client/pages/instance/federation.vue index fa7c377720..5babc60453 100644 --- a/src/client/pages/instance/federation.vue +++ b/src/client/pages/instance/federation.vue @@ -1,11 +1,14 @@ <template> <div class="mk-federation"> + <portal to="icon"><fa :icon="faGlobe"/></portal> + <portal to="title">{{ $t('federation') }}</portal> + <section class="_card instances"> - <div class="_title"><fa :icon="faGlobe"/> {{ $t('instances') }}</div> <div class="_content"> + <mk-input v-model="host" :debounce="true"><span>{{ $t('host') }}</span></mk-input> <div class="inputs" style="display: flex;"> - <mk-input v-model="host" :debounce="true" style="margin: 0; flex: 1;"><span>{{ $t('host') }}</span></mk-input> - <mk-select v-model="state" style="margin: 0;"> + <mk-select v-model="state" style="margin: 0; flex: 1;"> + <template #label>{{ $t('state') }}</template> <option value="all">{{ $t('all') }}</option> <option value="federating">{{ $t('federating') }}</option> <option value="subscribing">{{ $t('subscribing') }}</option> @@ -14,11 +17,32 @@ <option value="blocked">{{ $t('blocked') }}</option> <option value="notResponding">{{ $t('notResponding') }}</option> </mk-select> + <mk-select v-model="sort" style="margin: 0; flex: 1;"> + <template #label>{{ $t('sort') }}</template> + <option value="+pubSub">{{ $t('pubSub') }} ({{ $t('descendingOrder') }})</option> + <option value="-pubSub">{{ $t('pubSub') }} ({{ $t('ascendingOrder') }})</option> + <option value="+notes">{{ $t('notes') }} ({{ $t('descendingOrder') }})</option> + <option value="-notes">{{ $t('notes') }} ({{ $t('ascendingOrder') }})</option> + <option value="+users">{{ $t('users') }} ({{ $t('descendingOrder') }})</option> + <option value="-users">{{ $t('users') }} ({{ $t('ascendingOrder') }})</option> + <option value="+following">{{ $t('following') }} ({{ $t('descendingOrder') }})</option> + <option value="-following">{{ $t('following') }} ({{ $t('ascendingOrder') }})</option> + <option value="+followers">{{ $t('followers') }} ({{ $t('descendingOrder') }})</option> + <option value="-followers">{{ $t('followers') }} ({{ $t('ascendingOrder') }})</option> + <option value="+caughtAt">{{ $t('caughtAt') }} ({{ $t('descendingOrder') }})</option> + <option value="-caughtAt">{{ $t('caughtAt') }} ({{ $t('ascendingOrder') }})</option> + <option value="+lastCommunicatedAt">{{ $t('lastCommunicatedAt') }} ({{ $t('descendingOrder') }})</option> + <option value="-lastCommunicatedAt">{{ $t('lastCommunicatedAt') }} ({{ $t('ascendingOrder') }})</option> + <option value="+driveUsage">{{ $t('driveUsage') }} ({{ $t('descendingOrder') }})</option> + <option value="-driveUsage">{{ $t('driveUsage') }} ({{ $t('ascendingOrder') }})</option> + <option value="+driveFiles">{{ $t('driveFiles') }} ({{ $t('descendingOrder') }})</option> + <option value="-driveFiles">{{ $t('driveFiles') }} ({{ $t('ascendingOrder') }})</option> + </mk-select> </div> </div> <div class="_content"> <mk-pagination :pagination="pagination" #default="{items}" class="instances" ref="instances" :key="host + state"> - <div class="instance" v-for="(instance, i) in items" :key="instance.id" @click="info(instance)"> + <div class="instance" v-for="instance in items" :key="instance.id" @click="info(instance)"> <div class="host"><fa :icon="faCircle" class="indicator" :class="getStatus(instance)"/><b>{{ instance.host }}</b></div> <div class="status"> <span class="sub" v-if="instance.followersCount > 0"><fa :icon="faCaretDown" class="icon"/>Sub</span> diff --git a/src/client/pages/instance/queue.vue b/src/client/pages/instance/queue.vue index 8590f9ae23..c4892e88db 100644 --- a/src/client/pages/instance/queue.vue +++ b/src/client/pages/instance/queue.vue @@ -1,5 +1,8 @@ <template> <div> + <portal to="icon"><fa :icon="faExchangeAlt"/></portal> + <portal to="title">{{ $t('jobQueue') }}</portal> + <x-queue :connection="connection" domain="inbox"> <template #title><fa :icon="faExchangeAlt"/> In</template> </x-queue> diff --git a/src/client/pages/messaging/messaging-room.vue b/src/client/pages/messaging/messaging-room.vue index 0a20c56c29..317ad087fe 100644 --- a/src/client/pages/messaging/messaging-room.vue +++ b/src/client/pages/messaging/messaging-room.vue @@ -19,7 +19,7 @@ <button class="more _button" :class="{ fetching: fetchingMoreMessages }" v-if="existMoreMessages" @click="fetchMoreMessages" :disabled="fetchingMoreMessages"> <template v-if="fetchingMoreMessages"><fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreMessages ? $t('loading') : $t('loadMore') }} </button> - <x-list class="messages" :items="messages" v-slot="{ item: message, i }" direction="up" reversed> + <x-list class="messages" :items="messages" v-slot="{ item: message }" direction="up" reversed> <x-message :message="message" :is-group="group != null" :key="message.id"/> </x-list> </div> diff --git a/src/client/pages/miauth.vue b/src/client/pages/miauth.vue index 2ee0f23479..0e170af11a 100644 --- a/src/client/pages/miauth.vue +++ b/src/client/pages/miauth.vue @@ -68,8 +68,8 @@ export default Vue.extend({ icon(): string { return this.$route.query.icon; }, - permission(): string { - return this.$route.query.permission; + permission(): string[] { + return this.$route.query.permission ? this.$route.query.permission.split(',') : []; }, }, methods: { @@ -79,7 +79,7 @@ export default Vue.extend({ session: this.session, name: this.name, iconUrl: this.icon, - permission: this.permission || [], + permission: this.permission, }); this.state = 'accepted'; diff --git a/src/client/theme.ts b/src/client/theme.ts index cc69ee4060..2f4920e3af 100644 --- a/src/client/theme.ts +++ b/src/client/theme.ts @@ -27,7 +27,7 @@ export const builtinThemes = [ require('./themes/danboard.json5'), require('./themes/olive.json5'), require('./themes/tweetdeck.json5'), -]; +] as Theme[]; let timeout = null; @@ -66,16 +66,21 @@ export function applyTheme(theme: Theme, persist = true) { } } -function compile(theme: Theme): { [key: string]: string } { - function getColor(code: string): tinycolor.Instance { - // ref - if (code[0] == '@') { - return getColor(theme.props[code.substr(1)]); +function compile(theme: Theme): Record<string, string> { + function getColor(val: string): tinycolor.Instance { + // ref (prop) + if (val[0] === '@') { + return getColor(theme.props[val.substr(1)]); + } + + // ref (const) + else if (val[0] === '$') { + return getColor(theme.props[val]); } // func - if (code[0] == ':') { - const parts = code.split('<'); + else if (val[0] === ':') { + const parts = val.split('<'); const func = parts.shift().substr(1); const arg = parseFloat(parts.shift()); const color = getColor(parts.join('<')); @@ -87,12 +92,15 @@ function compile(theme: Theme): { [key: string]: string } { } } - return tinycolor(code); + // other case + return tinycolor(val); } const props = {}; for (const [k, v] of Object.entries(theme.props)) { + if (k.startsWith('$')) continue; // ignore const + props[k] = genValue(getColor(v)); } diff --git a/src/client/widgets/memo.vue b/src/client/widgets/memo.vue index 974c13eb0d..3c170adc4e 100644 --- a/src/client/widgets/memo.vue +++ b/src/client/widgets/memo.vue @@ -5,7 +5,7 @@ <div class="otgbylcu"> <textarea v-model="text" :placeholder="$t('placeholder')" @input="onChange"></textarea> - <button @click="saveMemo" :disabled="!changed">{{ $t('save') }}</button> + <button @click="saveMemo" :disabled="!changed" class="_buttonPrimary">{{ $t('save') }}</button> </div> </mk-container> </div> @@ -84,6 +84,7 @@ export default define({ border: none; border-bottom: solid var(--lineWidth) var(--faceDivider); border-radius: 0; + box-sizing: border-box; } > button { @@ -94,22 +95,8 @@ export default define({ margin: 0; padding: 0 10px; height: 28px; - color: #fff; - background: var(--accent) !important; outline: none; - border: none; border-radius: 4px; - transition: background 0.1s ease; - cursor: pointer; - - &:hover { - background: var(--accentLighten10) !important; - } - - &:active { - background: var(--accentDarken) !important; - transition: background 0s ease; - } &:disabled { opacity: 0.7; diff --git a/src/db/postgre.ts b/src/db/postgre.ts index 57703fb095..9e3eb3f7d6 100644 --- a/src/db/postgre.ts +++ b/src/db/postgre.ts @@ -69,7 +69,9 @@ class MyCustomLogger implements Logger { } public logQuery(query: string, parameters?: any[]) { - sqlLogger.info(this.highlight(query)); + if (program.verbose) { + sqlLogger.info(this.highlight(query)); + } } public logQueryError(error: string, query: string, parameters?: any[]) { @@ -158,7 +160,7 @@ export function initDb(justBorrow = false, sync = false, forceRecreate = false) } catch (e) {} } - const log = program.verbose; + const log = process.env.NODE_ENV != 'production'; return createConnection({ type: 'postgres', diff --git a/src/docs/theme.ja-JP.md b/src/docs/theme.ja-JP.md new file mode 100644 index 0000000000..c9604da412 --- /dev/null +++ b/src/docs/theme.ja-JP.md @@ -0,0 +1,74 @@ +# テーマ + +テーマを設定して、Misskeyクライアントの見た目を変更できます。 + +## テーマの設定 +設定 > テーマ + +## テーマを作成する +テーマコードはJSON5で記述されたテーマオブジェクトです。 +テーマは以下のようなオブジェクトです。 +``` js +{ + id: '17587283-dd92-4a2c-a22c-be0637c9e22a', + + name: 'Danboard', + author: 'syuilo', + + base: 'light', + + props: { + accent: 'rgb(218, 141, 49)', + bg: 'rgb(218, 212, 190)', + fg: 'rgb(115, 108, 92)', + panel: 'rgb(236, 232, 220)', + renote: 'rgb(100, 152, 106)', + link: 'rgb(100, 152, 106)', + mention: '@accent', + hashtag: 'rgb(100, 152, 106)', + header: 'rgba(239, 227, 213, 0.75)', + navBg: 'rgb(216, 206, 182)', + inputBorder: 'rgba(0, 0, 0, 0.1)', + }, +} + +``` + +* `id` ... テーマの一意なID。UUIDをおすすめします。 +* `name` ... テーマ名 +* `author` ... テーマの作者 +* `desc` ... テーマの説明(オプション) +* `base` ... 明るいテーマか、暗いテーマか + * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 + * テーマはここで設定されたベーステーマを継承します。 +* `props` ... テーマのスタイル定義。これから説明します。 + +### テーマのスタイル定義 +`props`下にはテーマのスタイルを定義します。 +キーがCSSの変数名になり、バリューで中身を指定します。 +なお、この`props`オブジェクトはベーステーマから継承されます。 +ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 +つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 + +#### バリューで使える構文 +* 16進数で表された色 + * 例: `#00ff00` +* `rgb(r, g, b)`形式で表された色 + * 例: `rgb(0, 255, 0)` +* `rgb(r, g, b, a)`形式で表された透明度を含む色 + * 例: `rgba(0, 255, 0, 0.5)` +* 他のキーの値の参照 + * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 + * 例: `@panel` +* 定数(後述)の参照 + * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 + * 例: `$main` +* 関数(後述) + * `:{関数名}<{引数}<{色}` + +#### 定数 +「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 +キー名を`$`で始めると、そのキーはCSS変数として出力されません。 + +#### 関数 +wip diff --git a/src/models/repositories/notification.ts b/src/models/repositories/notification.ts index a8978cc01b..b484c43c5e 100644 --- a/src/models/repositories/notification.ts +++ b/src/models/repositories/notification.ts @@ -46,8 +46,8 @@ export class NotificationRepository extends Repository<Notification> { } : {}), ...(notification.type === 'app' ? { body: notification.customBody, - header: notification.customHeader || token!.name, - icon: notification.customIcon || token!.iconUrl, + header: notification.customHeader || token?.name, + icon: notification.customIcon || token?.iconUrl, } : {}), }); } diff --git a/src/server/api/define.ts b/src/server/api/define.ts index 2ee0ba4868..1c7ee26479 100644 --- a/src/server/api/define.ts +++ b/src/server/api/define.ts @@ -15,12 +15,12 @@ type Params<T extends IEndpointMeta> = { export type Response = Record<string, any> | void; type executor<T extends IEndpointMeta> = - (params: Params<T>, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken, file?: any, cleanup?: Function) => + (params: Params<T>, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken | null, file?: any, cleanup?: Function) => Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>; export default function <T extends IEndpointMeta>(meta: T, cb: executor<T>) - : (params: any, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken, file?: any) => Promise<any> { - return (params: any, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken, file?: any) => { + : (params: any, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken | null, file?: any) => Promise<any> { + return (params: any, user: T['requireCredential'] extends true ? ILocalUser : ILocalUser | null, token: AccessToken | null, file?: any) => { function cleanup() { fs.unlink(file.path, () => {}); } diff --git a/src/server/api/endpoints/i/apps.ts b/src/server/api/endpoints/i/apps.ts index dc74123ce3..3b5cd21a79 100644 --- a/src/server/api/endpoints/i/apps.ts +++ b/src/server/api/endpoints/i/apps.ts @@ -38,5 +38,6 @@ export default define(meta, async (ps, user) => { name: token.name, createdAt: token.createdAt, lastUsedAt: token.lastUsedAt, + permission: token.permission, }))); }); diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts index 8eaa65a2c6..41adc855d2 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -159,6 +159,7 @@ export default define(meta, async (ps, me) => { github: instance.enableGithubIntegration, discord: instance.enableDiscordIntegration, serviceWorker: instance.enableServiceWorker, + miauth: true, }; } diff --git a/src/server/api/endpoints/notifications/create.ts b/src/server/api/endpoints/notifications/create.ts index fed422b645..6267699e90 100644 --- a/src/server/api/endpoints/notifications/create.ts +++ b/src/server/api/endpoints/notifications/create.ts @@ -29,7 +29,7 @@ export const meta = { export default define(meta, async (ps, user, token) => { createNotification(user.id, 'app', { - appAccessTokenId: token.id, + appAccessTokenId: token ? token.id : null, customBody: ps.body, customHeader: ps.header, customIcon: ps.icon, diff --git a/src/server/api/stream/index.ts b/src/server/api/stream/index.ts index 05594ac722..2781d14bd9 100644 --- a/src/server/api/stream/index.ts +++ b/src/server/api/stream/index.ts @@ -18,7 +18,7 @@ export default class Connection { public user?: User; public following: User['id'][] = []; public muting: User['id'][] = []; - public token: AccessToken; + public token?: AccessToken; private wsConnection: websocket.connection; public subscriber: EventEmitter; private channels: Channel[] = []; @@ -117,7 +117,7 @@ export default class Connection { this.subscribingNotes[payload.id]++; - if (this.subscribingNotes[payload.id] == 1) { + if (this.subscribingNotes[payload.id] === 1) { this.subscriber.on(`noteStream:${payload.id}`, this.onNoteStreamMessage); } |