Merge branch 'develop' into sw-notification-action

This commit is contained in:
tamaina 2021-02-17 22:03:30 +09:00 committed by GitHub
commit ffa1dc6219
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 88 additions and 39 deletions

View file

@ -0,0 +1,15 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class useBigintForDriveUsage1613503367223 implements MigrationInterface {
name = 'useBigintForDriveUsage1613503367223'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "driveUsage" TYPE bigint`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "driveUsage"`);
await queryRunner.query(`ALTER TABLE "instance" ADD "driveUsage" integer NOT NULL DEFAULT 0`);
}
}

View file

@ -3,7 +3,6 @@ import { reactive } from 'vue';
import { apiUrl } from '@/config'; import { apiUrl } from '@/config';
import { waiting } from '@/os'; import { waiting } from '@/os';
import { unisonReload, reloadChannel } from '@/scripts/unison-reload'; import { unisonReload, reloadChannel } from '@/scripts/unison-reload';
// TODO: 他のタブと永続化されたstateを同期 // TODO: 他のタブと永続化されたstateを同期
type Account = { type Account = {

View file

@ -99,7 +99,8 @@ import { faHeart, faFlag, faLaugh } from '@fortawesome/free-regular-svg-icons';
import MkModal from '@/components/ui/modal.vue'; import MkModal from '@/components/ui/modal.vue';
import Particle from '@/components/particle.vue'; import Particle from '@/components/particle.vue';
import * as os from '@/os'; import * as os from '@/os';
import { isDeviceTouch } from '../scripts/is-device-touch'; import { isDeviceTouch } from '@/scripts/is-device-touch';
import { isMobile } from '@/scripts/is-mobile';
import { emojiCategories } from '@/instance'; import { emojiCategories } from '@/instance';
export default defineComponent({ export default defineComponent({
@ -322,7 +323,7 @@ export default defineComponent({
}, },
mounted() { mounted() {
if (!os.isMobile) { if (!isMobile && !isDeviceTouch) {
this.$refs.search.focus({ this.$refs.search.focus({
preventScroll: true preventScroll: true
}); });

View file

@ -69,6 +69,7 @@ import { noteVisibilities } from '../../types';
import * as os from '@/os'; import * as os from '@/os';
import { selectFile } from '@/scripts/select-file'; import { selectFile } from '@/scripts/select-file';
import { notePostInterruptors, postFormActions } from '@/store'; import { notePostInterruptors, postFormActions } from '@/store';
import { isMobile } from '@/scripts/is-mobile';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -580,7 +581,7 @@ export default defineComponent({
localOnly: this.localOnly, localOnly: this.localOnly,
visibility: this.visibility, visibility: this.visibility,
visibleUserIds: this.visibility == 'specified' ? this.visibleUsers.map(u => u.id) : undefined, visibleUserIds: this.visibility == 'specified' ? this.visibleUsers.map(u => u.id) : undefined,
viaMobile: os.isMobile viaMobile: isMobile
}; };
// plugin // plugin

View file

@ -138,13 +138,19 @@ export default defineComponent({
}, },
async openAccountMenu(ev) { async openAccountMenu(ev) {
const storedAccounts = await getAccounts(); const storedAccounts = (await getAccounts()).filter(x => x.id !== this.$i.id);
const accounts = (await os.api('users/show', { userIds: storedAccounts.map(x => x.id) })).filter(x => x.id !== this.$i.id); const accountsPromise = os.api('users/show', { userIds: storedAccounts.map(x => x.id) });
const accountItems = accounts.map(account => ({ const accountItemPromises = storedAccounts.map(a => new Promise(res => {
type: 'user', accountsPromise.then(accounts => {
user: account, const account = accounts.find(x => x.id === a.id);
action: () => { this.switchAccount(account); } if (account == null) return res(null);
res({
type: 'user',
user: account,
action: () => { this.switchAccount(account); }
});
});
})); }));
os.modalMenu([...[{ os.modalMenu([...[{
@ -152,7 +158,7 @@ export default defineComponent({
text: this.$ts.profile, text: this.$ts.profile,
to: `/@${ this.$i.username }`, to: `/@${ this.$i.username }`,
avatar: this.$i, avatar: this.$i,
}, null, ...accountItems, { }, null, ...accountItemPromises, {
icon: faPlus, icon: faPlus,
text: this.$ts.addAcount, text: this.$ts.addAcount,
action: () => { action: () => {

View file

@ -56,13 +56,14 @@ import { router } from '@/router';
import { applyTheme } from '@/scripts/theme'; import { applyTheme } from '@/scripts/theme';
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode'; import { isDeviceDarkmode } from '@/scripts/is-device-darkmode';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
import { stream, isMobile, dialog, post } from '@/os'; import { stream, dialog, post } from '@/os';
import * as sound from '@/scripts/sound'; import * as sound from '@/scripts/sound';
import { $i, refreshAccount, login, updateAccount, signout } from '@/account'; import { $i, refreshAccount, login, updateAccount, signout } from '@/account';
import { defaultStore, ColdDeviceStorage } from '@/store'; import { defaultStore, ColdDeviceStorage } from '@/store';
import { fetchInstance, instance } from '@/instance'; import { fetchInstance, instance } from '@/instance';
import { makeHotkey } from '@/scripts/hotkey'; import { makeHotkey } from '@/scripts/hotkey';
import { search } from '@/scripts/search'; import { search } from '@/scripts/search';
import { isMobile } from '@/scripts/is-mobile';
import { getThemes } from '@/theme-store'; import { getThemes } from '@/theme-store';
import { initializeSw } from '@/scripts/initialize-sw'; import { initializeSw } from '@/scripts/initialize-sw';
import { reloadChannel } from '@/scripts/unison-reload'; import { reloadChannel } from '@/scripts/unison-reload';

View file

@ -9,9 +9,6 @@ import { resolve } from '@/router';
import { $i } from '@/account'; import { $i } from '@/account';
import { defaultStore } from '@/store'; import { defaultStore } from '@/store';
const ua = navigator.userAgent.toLowerCase();
export const isMobile = /mobile|iphone|ipad|android/.test(ua);
export const stream = markRaw(new Stream()); export const stream = markRaw(new Stream());
export const pendingApiRequestsCount = ref(0); export const pendingApiRequestsCount = ref(0);

View file

@ -0,0 +1,2 @@
const ua = navigator.userAgent.toLowerCase();
export const isMobile = /mobile|iphone|ipad|android/.test(ua);

View file

@ -16,6 +16,8 @@
bg: '#000', bg: '#000',
acrylicBg: ':alpha<0.5<@bg', acrylicBg: ':alpha<0.5<@bg',
fg: '#dadada', fg: '#dadada',
fgTransparentWeak: ':alpha<0.75<@fg',
fgTransparent: ':alpha<0.5<@fg',
fgHighlighted: ':lighten<3<@fg', fgHighlighted: ':lighten<3<@fg',
divider: 'rgba(255, 255, 255, 0.1)', divider: 'rgba(255, 255, 255, 0.1)',
indicator: '@accent', indicator: '@accent',
@ -77,5 +79,6 @@
X14: ':alpha<0.5<@navBg', X14: ':alpha<0.5<@navBg',
X15: ':alpha<0<@panel', X15: ':alpha<0<@panel',
X16: ':alpha<0.7<@panel', X16: ':alpha<0.7<@panel',
X17: ':alpha<0.8<@bg',
}, },
} }

View file

@ -16,6 +16,8 @@
bg: '#fff', bg: '#fff',
acrylicBg: ':alpha<0.5<@bg', acrylicBg: ':alpha<0.5<@bg',
fg: '#5f5f5f', fg: '#5f5f5f',
fgTransparentWeak: ':alpha<0.75<@fg',
fgTransparent: ':alpha<0.5<@fg',
fgHighlighted: ':darken<3<@fg', fgHighlighted: ':darken<3<@fg',
divider: 'rgba(0, 0, 0, 0.1)', divider: 'rgba(0, 0, 0, 0.1)',
indicator: '@accent', indicator: '@accent',
@ -77,5 +79,6 @@
X14: ':alpha<0.5<@navBg', X14: ':alpha<0.5<@navBg',
X15: ':alpha<0<@panel', X15: ':alpha<0<@panel',
X16: ':alpha<0.7<@panel', X16: ':alpha<0.7<@panel',
X17: ':alpha<0.8<@bg',
}, },
} }

View file

@ -200,6 +200,11 @@ export default defineComponent({
}, },
created() { created() {
if (window.innerWidth < 1024) {
localStorage.setItem('ui', 'default');
location.reload();
}
router.beforeEach((to, from) => { router.beforeEach((to, from) => {
this.$refs.side.navigate(to.fullPath); this.$refs.side.navigate(to.fullPath);
// search?q=foo return false // search?q=foo return false
@ -414,10 +419,12 @@ export default defineComponent({
> .body { > .body {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
padding: 8px 0;
overflow: auto; overflow: auto;
> .container { > .container {
margin-top: 8px;
margin-bottom: 8px;
& + .container { & + .container {
margin-top: 16px; margin-top: 16px;
} }
@ -426,10 +433,21 @@ export default defineComponent({
display: flex; display: flex;
font-size: 0.9em; font-size: 0.9em;
padding: 8px 16px; padding: 8px 16px;
opacity: 0.7; position: sticky;
top: 0;
background: var(--X17);
-webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(8px);
z-index: 1;
color: var(--fgTransparentWeak);
> .add { > .add {
margin-left: auto; margin-left: auto;
color: var(--fgTransparentWeak);
&:hover {
color: var(--fg);
}
} }
} }
@ -448,11 +466,11 @@ export default defineComponent({
&.active, &.active:hover { &.active, &.active:hover {
background: var(--accent); background: var(--accent);
color: #fff; color: #fff !important;
} }
&.read { &.read {
opacity: 0.5; color: var(--fgTransparent);
} }
> .icon { > .icon {
@ -527,6 +545,7 @@ export default defineComponent({
> .instance { > .instance {
margin-right: 16px; margin-right: 16px;
font-size: 0.9em;
} }
> .clock { > .clock {

View file

@ -65,21 +65,21 @@
</div> </div>
<XReactionsViewer :note="appearNote" ref="reactionsViewer"/> <XReactionsViewer :note="appearNote" ref="reactionsViewer"/>
<footer class="footer _panel"> <footer class="footer _panel">
<button @click="reply()" class="button _button"> <button @click="reply()" class="button _button" v-tooltip="$ts.reply">
<template v-if="appearNote.reply"><Fa :icon="faReplyAll"/></template> <template v-if="appearNote.reply"><Fa :icon="faReplyAll"/></template>
<template v-else><Fa :icon="faReply"/></template> <template v-else><Fa :icon="faReply"/></template>
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p> <p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
</button> </button>
<button v-if="canRenote" @click="renote()" class="button _button" ref="renoteButton"> <button v-if="canRenote" @click="renote()" class="button _button" ref="renoteButton" v-tooltip="$ts.renote">
<Fa :icon="faRetweet"/><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p> <Fa :icon="faRetweet"/><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
</button> </button>
<button v-else class="button _button"> <button v-else class="button _button">
<Fa :icon="faBan"/> <Fa :icon="faBan"/>
</button> </button>
<button v-if="appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton"> <button v-if="appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton" v-tooltip="$ts.reaction">
<Fa :icon="faPlus"/> <Fa :icon="faPlus"/>
</button> </button>
<button v-if="appearNote.myReaction != null" class="button _button reacted" @click="undoReact(appearNote)" ref="reactButton"> <button v-if="appearNote.myReaction != null" class="button _button reacted" @click="undoReact(appearNote)" ref="reactButton" v-tooltip="$ts.reaction">
<Fa :icon="faMinus"/> <Fa :icon="faMinus"/>
</button> </button>
<button class="button _button" @click="menu()" ref="menuButton"> <button class="button _button" @click="menu()" ref="menuButton">
@ -911,7 +911,7 @@ export default defineComponent({
align-items: center; align-items: center;
padding: 12px 16px 4px 16px; padding: 12px 16px 4px 16px;
line-height: 24px; line-height: 24px;
font-size: 90%; font-size: 85%;
white-space: pre; white-space: pre;
color: #d28a3f; color: #d28a3f;

View file

@ -64,6 +64,7 @@ import { noteVisibilities } from '../../../types';
import * as os from '@/os'; import * as os from '@/os';
import { selectFile } from '@/scripts/select-file'; import { selectFile } from '@/scripts/select-file';
import { notePostInterruptors, postFormActions } from '@/store'; import { notePostInterruptors, postFormActions } from '@/store';
import { isMobile } from '@/scripts/is-mobile';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -541,7 +542,7 @@ export default defineComponent({
localOnly: this.localOnly, localOnly: this.localOnly,
visibility: this.visibility, visibility: this.visibility,
visibleUserIds: this.visibility == 'specified' ? this.visibleUsers.map(u => u.id) : undefined, visibleUserIds: this.visibility == 'specified' ? this.visibleUsers.map(u => u.id) : undefined,
viaMobile: os.isMobile viaMobile: isMobile
}; };
// plugin // plugin

View file

@ -12,7 +12,7 @@ import { extractApHashtags } from './tag';
import { apLogger } from '../logger'; import { apLogger } from '../logger';
import { Note } from '../../../models/entities/note'; import { Note } from '../../../models/entities/note';
import { updateUsertags } from '../../../services/update-hashtag'; import { updateUsertags } from '../../../services/update-hashtag';
import { Users, UserNotePinings, Instances, DriveFiles, Followings, UserProfiles, UserPublickeys } from '../../../models'; import { Users, Instances, DriveFiles, Followings, UserProfiles, UserPublickeys } from '../../../models';
import { User, IRemoteUser } from '../../../models/entities/user'; import { User, IRemoteUser } from '../../../models/entities/user';
import { Emoji } from '../../../models/entities/emoji'; import { Emoji } from '../../../models/entities/emoji';
import { UserNotePining } from '../../../models/entities/user-note-pining'; import { UserNotePining } from '../../../models/entities/user-note-pining';
@ -479,18 +479,19 @@ export async function updateFeatured(userId: User['id']) {
.slice(0, 5) .slice(0, 5)
.map(item => limit(() => resolveNote(item, resolver)))); .map(item => limit(() => resolveNote(item, resolver))));
// delete await getConnection().transaction(async transactionalEntityManager => {
await UserNotePinings.delete({ userId: user.id }); await transactionalEntityManager.delete(UserNotePining, { userId: user.id });
// とりあえずidを別の時間で生成して順番を維持 // とりあえずidを別の時間で生成して順番を維持
let td = 0; let td = 0;
for (const note of featuredNotes.filter(note => note != null)) { for (const note of featuredNotes.filter(note => note != null)) {
td -= 1000; td -= 1000;
UserNotePinings.save({ transactionalEntityManager.insert(UserNotePining, {
id: genId(new Date(Date.now() + td)), id: genId(new Date(Date.now() + td)),
createdAt: new Date(), createdAt: new Date(),
userId: user.id, userId: user.id,
noteId: note!.id noteId: note!.id
} as UserNotePining); });
} }
});
} }