{{ $ts._mfm.sparkleDescription }}
+
-
-
+
+
@@ -63,12 +65,14 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: computed(() => this.note ? {
title: this.$ts.note,
+ subtitle: new Date(this.note.createdAt).toLocaleString(),
avatar: this.note.user,
path: `/notes/${this.note.id}`,
share: {
title: this.$t('noteOf', { user: this.note.user.name }),
text: this.note.text,
},
+ bg: 'var(--bg)',
} : null),
note: null,
clips: null,
@@ -149,52 +153,54 @@ export default defineComponent({
.fcuexfpr {
background: var(--bg);
- > .note {
- > .main {
- > .load {
- min-width: 0;
- margin: 0 auto;
- border-radius: 999px;
+ > ._root {
+ > .note {
+ > .main {
+ > .load {
+ min-width: 0;
+ margin: 0 auto;
+ border-radius: 999px;
- &.next {
- margin-bottom: var(--margin);
- }
+ &.next {
+ margin-bottom: var(--margin);
+ }
- &.prev {
- margin-top: var(--margin);
+ &.prev {
+ margin-top: var(--margin);
+ }
}
- }
- > .note {
> .note {
- border-radius: var(--radius);
- background: var(--panel);
+ > .note {
+ border-radius: var(--radius);
+ background: var(--panel);
+ }
}
- }
- > .clips {
- > .title {
- font-weight: bold;
- padding: 12px;
- }
+ > .clips {
+ > .title {
+ font-weight: bold;
+ padding: 12px;
+ }
- > .item {
- display: block;
- padding: 16px;
+ > .item {
+ display: block;
+ padding: 16px;
- > .description {
- padding: 8px 0;
- }
+ > .description {
+ padding: 8px 0;
+ }
- > .user {
- $height: 32px;
- padding-top: 16px;
- border-top: solid 0.5px var(--divider);
- line-height: $height;
+ > .user {
+ $height: 32px;
+ padding-top: 16px;
+ border-top: solid 0.5px var(--divider);
+ line-height: $height;
- > .avatar {
- width: $height;
- height: $height;
+ > .avatar {
+ width: $height;
+ height: $height;
+ }
}
}
}
diff --git a/src/client/pages/notifications.vue b/src/client/pages/notifications.vue
index 633718a90b..06f8ad3cba 100644
--- a/src/client/pages/notifications.vue
+++ b/src/client/pages/notifications.vue
@@ -21,6 +21,7 @@ export default defineComponent({
[symbols.PAGE_INFO]: {
title: this.$ts.notifications,
icon: 'fas fa-bell',
+ bg: 'var(--bg)',
actions: [{
text: this.$ts.markAllAsRead,
icon: 'fas fa-check',
diff --git a/src/client/pages/settings/index.vue b/src/client/pages/settings/index.vue
index e7e2506020..3fb5f5f1e6 100644
--- a/src/client/pages/settings/index.vue
+++ b/src/client/pages/settings/index.vue
@@ -86,7 +86,8 @@ export default defineComponent({
setup(props, context) {
const indexInfo = {
title: i18n.locale.settings,
- icon: 'fas fa-cog'
+ icon: 'fas fa-cog',
+ bg: 'var(--bg)',
};
const INFO = ref(indexInfo);
const page = ref(props.initialPage);
diff --git a/src/client/pages/timeline.vue b/src/client/pages/timeline.vue
index f54549b982..125191223c 100644
--- a/src/client/pages/timeline.vue
+++ b/src/client/pages/timeline.vue
@@ -1,25 +1,10 @@
+
+
-
-
+
+
+
+
+
-
+
-
-
- {{ item.name }}
-
+
+
-
- {{ $ts.clip }}
- {{ item.description }}
-
-
-
-
+
+
-
+
+
+
+
+
+ {{ item.name }}
+
+
+ {{ $ts.clip }}
+ {{ item.description }}
+
+
+
+
-
+
-
+
+
-
-
-
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
({
title: this.$ts.timeline,
- subtitle: this.src === 'local' ? this.$ts._timelines.local : this.src === 'social' ? this.$ts._timelines.social : this.src === 'global' ? this.$ts._timelines.global : this.$ts._timelines.home,
icon: this.src === 'local' ? 'fas fa-comments' : this.src === 'social' ? 'fas fa-share-alt' : this.src === 'global' ? 'fas fa-globe' : 'fas fa-home',
+ bg: 'var(--bg)',
actions: [{
icon: 'fas fa-calendar-alt',
text: this.$ts.jumpToSpecifiedDate,
handler: this.timetravel
+ }],
+ tabs: [{
+ active: this.src === 'home',
+ title: this.$ts._timelines.home,
+ icon: 'fas fa-home',
+ iconOnly: true,
+ onClick: () => { this.src = 'home'; this.saveSrc(); },
+ }, {
+ active: this.src === 'local',
+ title: this.$ts._timelines.local,
+ icon: 'fas fa-comments',
+ iconOnly: true,
+ onClick: () => { this.src = 'local'; this.saveSrc(); },
+ }, {
+ active: this.src === 'social',
+ title: this.$ts._timelines.social,
+ icon: 'fas fa-share-alt',
+ iconOnly: true,
+ onClick: () => { this.src = 'social'; this.saveSrc(); },
+ }, {
+ active: this.src === 'global',
+ title: this.$ts._timelines.global,
+ icon: 'fas fa-globe',
+ iconOnly: true,
+ onClick: () => { this.src = 'global'; this.saveSrc(); },
}]
})),
};
@@ -213,6 +223,8 @@ export default defineComponent({
diff --git a/src/client/pages/user/index.vue b/src/client/pages/user/index.vue
index 4145c86d56..86dc7361b5 100644
--- a/src/client/pages/user/index.vue
+++ b/src/client/pages/user/index.vue
@@ -60,23 +60,9 @@
-
-
-
- {{ $ts.notes }}
-
-
-
- {{ $ts.clips }}
-
-
-
- {{ $ts.pages }}
-
-
-
-
-
+
+
+
@@ -178,25 +164,6 @@
-
-
-
- {{ $ts.notes }}
-
-
-
- {{ $ts.clips }}
-
-
-
- {{ $ts.pages }}
-
-
-
- {{ $ts.gallery }}
-
-
-
@@ -283,6 +250,27 @@ export default defineComponent({
share: {
title: this.user.name,
},
+ bg: 'var(--bg)',
+ tabs: [{
+ active: this.page === 'index',
+ title: this.$ts.overview,
+ icon: 'fas fa-home',
+ }, {
+ active: this.page === 'clips',
+ title: this.$ts.clips,
+ icon: 'fas fa-paperclip',
+ onClick: () => { this.page = 'clips'; },
+ }, {
+ active: this.page === 'pages',
+ title: this.$ts.pages,
+ icon: 'fas fa-file-alt',
+ onClick: () => { this.page = 'pages'; },
+ }, {
+ active: this.page === 'gallery',
+ title: this.$ts.gallery,
+ icon: 'fas fa-icons',
+ onClick: () => { this.page = 'gallery'; },
+ }]
} : null),
user: null,
error: null,
@@ -314,7 +302,7 @@ export default defineComponent({
mounted() {
window.requestAnimationFrame(this.parallaxLoop);
- this.narrow = this.$el.clientWidth < 1000;
+ this.narrow = true//this.$el.clientWidth < 1000;
},
beforeUnmount() {
@@ -772,37 +760,6 @@ export default defineComponent({
}
> .contents {
- > .nav {
- display: flex;
- align-items: center;
- font-size: 90%;
-
- > .link {
- flex: 1;
- display: inline-block;
- padding: 16px;
- text-align: center;
- border-bottom: solid 3px transparent;
-
- &:hover {
- text-decoration: none;
- }
-
- &.active {
- color: var(--accent);
- border-bottom-color: var(--accent);
- }
-
- &:not(.active):hover {
- color: var(--fgHighlighted);
- }
-
- > .icon {
- margin-right: 6px;
- }
- }
- }
-
> .content {
margin-bottom: var(--margin);
}
diff --git a/src/client/style.scss b/src/client/style.scss
index 6ab5e796bd..0318013f60 100644
--- a/src/client/style.scss
+++ b/src/client/style.scss
@@ -245,7 +245,6 @@ hr {
._panel {
background: var(--panel);
border-radius: var(--radius);
- border: var(--panelBorder);
overflow: clip;
}
diff --git a/src/client/themes/_dark.json5 b/src/client/themes/_dark.json5
index ca9994d5e9..b4553ee812 100644
--- a/src/client/themes/_dark.json5
+++ b/src/client/themes/_dark.json5
@@ -36,7 +36,7 @@
navFg: '@fg',
navHoverFg: ':lighten<17<@fg',
navActive: '@accent',
- navIndicator: '@accent',
+ navIndicator: '@indicator',
link: '#44a4c1',
hashtag: '#ff9156',
mention: '@accent',
diff --git a/src/client/themes/_light.json5 b/src/client/themes/_light.json5
index 973a6251f0..104f5a85af 100644
--- a/src/client/themes/_light.json5
+++ b/src/client/themes/_light.json5
@@ -36,7 +36,7 @@
navFg: '@fg',
navHoverFg: ':darken<17<@fg',
navActive: '@accent',
- navIndicator: '@accent',
+ navIndicator: '@indicator',
link: '#44a4c1',
hashtag: '#ff9156',
mention: '@accent',
diff --git a/src/client/ui/_common_/header.vue b/src/client/ui/_common_/header.vue
index 115f70a540..eb8a1b9c0a 100644
--- a/src/client/ui/_common_/header.vue
+++ b/src/client/ui/_common_/header.vue
@@ -1,25 +1,35 @@
-
+
-
+
+
+
@@ -145,6 +145,15 @@ export default defineComponent({
}
}, '*');
}, { passive: true });
+ window.addEventListener('touchmove', ev => {
+ this.$refs.live2d.contentWindow.postMessage({
+ type: 'moveCursor',
+ body: {
+ x: ev.touches[0].clientX - iframeRect.left,
+ y: ev.touches[0].clientY - iframeRect.top,
+ }
+ }, '*');
+ }, { passive: true });
}
},
diff --git a/src/client/ui/universal.vue b/src/client/ui/universal.vue
index d6cace0f41..cc754cba70 100644
--- a/src/client/ui/universal.vue
+++ b/src/client/ui/universal.vue
@@ -2,8 +2,8 @@
- ${this.$ts._mfm.dummy} `,
@@ -317,6 +327,7 @@ export default defineComponent({
preview_x4: `$[x4 🍮]`,
preview_blur: `$[blur ${this.$ts._mfm.dummy}]`,
preview_rainbow: `$[rainbow 🍮]`,
+ preview_sparkle: `$[sparkle 🍮]`,
}
},
});
--
cgit v1.2.3-freya
From fbbce302bc541ba7eb30f11e908ade95100bab43 Mon Sep 17 00:00:00 2001
From: syuilo
Date: Wed, 22 Sep 2021 22:18:08 +0900
Subject: enhance(client): 非ログイン自は更新ダイアログを出さないように
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolve #7756
---
CHANGELOG.md | 1 +
src/client/init.ts | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)
(limited to 'src/client')
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3c79ba0f80..9a0e754041 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@
- リスト、アンテナタイムラインを個別ページとして分割
- UIの改善
- MFMにsparklesエフェクトを追加
+- 非ログイン自は更新ダイアログを出さないように
### Bugfixes
- アカウントデータのエクスポート/インポート処理ができない問題を修正
diff --git a/src/client/init.ts b/src/client/init.ts
index aa9cd817c4..c15374e49b 100644
--- a/src/client/init.ts
+++ b/src/client/init.ts
@@ -217,7 +217,10 @@ if (lastVersion !== version) {
try { // 変なバージョン文字列来るとcompareVersionsでエラーになるため
if (lastVersion != null && compareVersions(version, lastVersion) === 1) {
- popup(import('@client/components/updated.vue'), {}, {}, 'closed');
+ // ログインしてる場合だけ
+ if ($i) {
+ popup(import('@client/components/updated.vue'), {}, {}, 'closed');
+ }
}
} catch (e) {
}
--
cgit v1.2.3-freya
{{ info.title }}
-
+
{{ info.subtitle }}
+
+ {{ info.tabs.find(tab => tab.active)?.title }}
+
+
+
+
-
+
@@ -52,24 +62,28 @@ export default defineComponent({
required: false,
default: false,
},
- center: {
+ titleOnly: {
type: Boolean,
required: false,
- default: true,
+ default: false,
},
},
data() {
return {
- showActions: false,
+ narrow: false,
height: 0,
key: 0,
};
},
computed: {
+ hasTabs(): boolean {
+ return this.info.tabs && this.info.tabs.length > 0;
+ },
+
shouldShowMenu() {
- if (this.info.actions != null && !this.showActions) return true;
+ if (this.info.actions != null && this.narrow) return true;
if (this.info.menu != null) return true;
if (this.info.share != null) return true;
if (this.menu != null) return true;
@@ -85,10 +99,10 @@ export default defineComponent({
mounted() {
this.height = this.$el.parentElement.offsetHeight + 'px';
- this.showActions = this.$el.parentElement.offsetWidth >= 500;
+ this.narrow = this.titleOnly || this.$el.parentElement.offsetWidth < 500;
new ResizeObserver((entries, observer) => {
this.height = this.$el.parentElement.offsetHeight + 'px';
- this.showActions = this.$el.parentElement.offsetWidth >= 500;
+ this.narrow = this.titleOnly || this.$el.parentElement.offsetWidth < 500;
}).observe(this.$el);
},
@@ -102,7 +116,7 @@ export default defineComponent({
showMenu(ev) {
let menu = this.info.menu ? this.info.menu() : [];
- if (!this.showActions && this.info.actions) {
+ if (this.narrow && this.info.actions) {
menu = [...this.info.actions.map(x => ({
text: x.text,
icon: x.icon,
@@ -124,6 +138,18 @@ export default defineComponent({
popupMenu(menu, ev.currentTarget || ev.target);
},
+ showTabsPopup(ev) {
+ if (!this.hasTabs) return;
+ ev.preventDefault();
+ ev.stopPropagation();
+ const menu = this.info.tabs.map(tab => ({
+ text: tab.title,
+ icon: tab.icon,
+ action: tab.onClick,
+ }));
+ popupMenu(menu, ev.currentTarget || ev.target);
+ },
+
preventDrag(ev) {
ev.stopPropagation();
}
@@ -135,7 +161,7 @@ export default defineComponent({
.fdidabkb {
display: flex;
- &.center {
+ &.slim {
text-align: center;
> .titleContainer {
@@ -190,6 +216,7 @@ export default defineComponent({
overflow: auto;
white-space: nowrap;
text-align: left;
+ font-weight: bold;
> .avatar {
$size: 32px;
@@ -219,6 +246,54 @@ export default defineComponent({
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
+
+ &.activeTab {
+ text-align: center;
+
+ > .chevron {
+ display: inline-block;
+ margin-left: 6px;
+ }
+ }
+ }
+ }
+ }
+
+ > .tabs {
+ margin-left: 16px;
+ font-size: 0.8em;
+
+ > .tab {
+ display: inline-block;
+ position: relative;
+ padding: 0 10px;
+ height: 100%;
+ font-weight: normal;
+ opacity: 0.7;
+
+ &:hover {
+ opacity: 1;
+ }
+
+ &.active {
+ opacity: 1;
+
+ &:after {
+ content: "";
+ display: block;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+ width: 100%;
+ height: 3px;
+ background: var(--accent);
+ }
+ }
+
+ > .icon + .title {
+ margin-left: 8px;
}
}
}
diff --git a/src/client/ui/default.vue b/src/client/ui/default.vue
index eef693faef..a5ec243e9e 100644
--- a/src/client/ui/default.vue
+++ b/src/client/ui/default.vue
@@ -12,7 +12,7 @@
-
-
+
@@ -294,7 +304,7 @@ export default defineComponent({
preview_hashtag: '#test',
preview_url: `https://example.com`,
preview_link: `[${this.$ts._mfm.dummy}](https://example.com)`,
- preview_emoji: `:${this.$instance.emojis[0].name}:`,
+ preview_emoji: this.$instance.emojis.length ? `:${this.$instance.emojis[0].name}:` : `:emojiname:`,
preview_bold: `**${this.$ts._mfm.dummy}**`,
preview_small: `${this.$ts._mfm.dummy}`,
preview_center: `
+
@@ -258,7 +258,6 @@ export default defineComponent({
}
> .sidebar {
- border-right: solid 0.5px var(--divider);
}
> .contents {
@@ -313,7 +312,8 @@ export default defineComponent({
> .widgets {
padding: 0 var(--margin);
- border-left: solid 0.5px var(--divider);
+ //border-left: solid 0.5px var(--divider);
+ background: var(--navBg);
@media (max-width: $widgets-hide-threshold) {
display: none;
--
cgit v1.2.3-freya
From 5141afe476fdc0312bb9bbcf127d3fef5dc7ec9f Mon Sep 17 00:00:00 2001
From: syuilo
Date: Sat, 18 Sep 2021 15:39:01 +0900
Subject: fix(client): タイムラインでリストとかなかったの修正
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/client/pages/timeline.vue | 12 ++++++++++++
1 file changed, 12 insertions(+)
(limited to 'src/client')
diff --git a/src/client/pages/timeline.vue b/src/client/pages/timeline.vue
index 125191223c..4b5b90e6ae 100644
--- a/src/client/pages/timeline.vue
+++ b/src/client/pages/timeline.vue
@@ -51,6 +51,18 @@ export default defineComponent({
icon: this.src === 'local' ? 'fas fa-comments' : this.src === 'social' ? 'fas fa-share-alt' : this.src === 'global' ? 'fas fa-globe' : 'fas fa-home',
bg: 'var(--bg)',
actions: [{
+ icon: 'fas fa-list-ul',
+ text: this.$ts.lists,
+ handler: this.chooseList
+ }, {
+ icon: 'fas fa-satellite',
+ text: this.$ts.antennas,
+ handler: this.chooseAntenna
+ }, {
+ icon: 'fas fa-satellite-dish',
+ text: this.$ts.channel,
+ handler: this.chooseChannel
+ }, {
icon: 'fas fa-calendar-alt',
text: this.$ts.jumpToSpecifiedDate,
handler: this.timetravel
--
cgit v1.2.3-freya
From 6d4e96dea257bbc0d1137dc2701d6e14fd539bc3 Mon Sep 17 00:00:00 2001
From: syuilo
Date: Sat, 18 Sep 2021 21:26:31 +0900
Subject: fix style
---
src/client/components/page-window.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src/client')
diff --git a/src/client/components/page-window.vue b/src/client/components/page-window.vue
index c83b040dd8..fbc9f0b7fd 100644
--- a/src/client/components/page-window.vue
+++ b/src/client/components/page-window.vue
@@ -8,7 +8,7 @@
@closed="$emit('closed')"
>
-
+
--
cgit v1.2.3-freya
From 54e0a7f8a8d977c7befc255cc4950a86ac2e72fb Mon Sep 17 00:00:00 2001
From: syuilo
Date: Sun, 19 Sep 2021 02:23:12 +0900
Subject: feat: 凍結された場合のダイアログを実装 (#7811)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: 凍結された場合のダイアログを実装
* Update CHANGELOG.md
* Update basic.js
* improve error handling
* cypressなんもわからん
* Update basic.js
---
CHANGELOG.md | 2 +
cypress/integration/basic.js | 142 ++++++++++++++++++++++------
locales/ja-JP.yml | 2 +
src/client/account.ts | 22 +++--
src/client/components/signin.vue | 41 +++++---
src/client/scripts/show-suspended-dialog.ts | 10 ++
src/server/api/endpoints/reset-db.ts | 2 +
src/server/api/private/signin.ts | 37 ++++----
8 files changed, 189 insertions(+), 69 deletions(-)
create mode 100644 src/client/scripts/show-suspended-dialog.ts
(limited to 'src/client')
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dce25340f9..8a15faf6a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,8 @@
### Improvements
- ActivityPub: リモートユーザーのDeleteアクティビティに対応
- ActivityPub: add resolver check for blocked instance
+- アカウントが凍結された場合に、凍結された旨を表示してからログアウトするように
+- 凍結されたアカウントにログインしようとしたときに、凍結されている旨を表示するように
- UIの改善
### Bugfixes
diff --git a/cypress/integration/basic.js b/cypress/integration/basic.js
index 69d59bc2c6..52bcdb58d0 100644
--- a/cypress/integration/basic.js
+++ b/cypress/integration/basic.js
@@ -1,12 +1,18 @@
describe('Basic', () => {
- before(() => {
- cy.request('POST', '/api/reset-db');
- });
-
beforeEach(() => {
+ cy.request('POST', '/api/reset-db').as('reset');
+ cy.get('@reset').its('status').should('equal', 204);
+ cy.clearLocalStorage();
+ cy.clearCookies();
cy.reload(true);
});
+ afterEach(() => {
+ // テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
+ // waitを入れることでそれを防止できる
+ cy.wait(1000);
+ });
+
it('successfully loads', () => {
cy.visit('/');
});
@@ -14,56 +20,130 @@ describe('Basic', () => {
it('setup instance', () => {
cy.visit('/');
+ cy.intercept('POST', '/api/admin/accounts/create').as('signup');
+
cy.get('[data-cy-admin-username] input').type('admin');
-
cy.get('[data-cy-admin-password] input').type('admin1234');
-
cy.get('[data-cy-admin-ok]').click();
+
+ // なぜか動かない
+ //cy.wait('@signup').should('have.property', 'response.statusCode');
+ cy.wait('@signup');
});
it('signup', () => {
- cy.visit('/');
+ // インスタンス初期セットアップ
+ cy.request('POST', '/api/admin/accounts/create', {
+ username: 'admin',
+ password: 'pass',
+ }).as('setup');
- cy.get('[data-cy-signup]').click();
+ cy.get('@setup').then(() => {
+ cy.visit('/');
- cy.get('[data-cy-signup-username] input').type('alice');
+ cy.intercept('POST', '/api/signup').as('signup');
- cy.get('[data-cy-signup-password] input').type('alice1234');
-
- cy.get('[data-cy-signup-password-retype] input').type('alice1234');
+ cy.get('[data-cy-signup]').click();
+ cy.get('[data-cy-signup-username] input').type('alice');
+ cy.get('[data-cy-signup-password] input').type('alice1234');
+ cy.get('[data-cy-signup-password-retype] input').type('alice1234');
+ cy.get('[data-cy-signup-submit]').click();
- cy.get('[data-cy-signup-submit]').click();
+ cy.wait('@signup');
+ });
});
it('signin', () => {
- cy.visit('/');
-
- cy.get('[data-cy-signin]').click();
-
- cy.get('[data-cy-signin-username] input').type('alice');
-
- // Enterキーでサインインできるかの確認も兼ねる
- cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
+ // インスタンス初期セットアップ
+ cy.request('POST', '/api/admin/accounts/create', {
+ username: 'admin',
+ password: 'pass',
+ }).as('setup');
+
+ cy.get('@setup').then(() => {
+ // ユーザー作成
+ cy.request('POST', '/api/signup', {
+ username: 'alice',
+ password: 'alice1234',
+ }).as('signup');
+ });
+
+ cy.get('@signup').then(() => {
+ cy.visit('/');
+
+ cy.intercept('POST', '/api/signin').as('signin');
+
+ cy.get('[data-cy-signin]').click();
+ cy.get('[data-cy-signin-username] input').type('alice');
+ // Enterキーでサインインできるかの確認も兼ねる
+ cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
+
+ cy.wait('@signin');
+ });
});
it('note', () => {
cy.visit('/');
- //#region TODO: この辺はUI操作ではなくAPI操作でログインする
- cy.get('[data-cy-signin]').click();
+ // インスタンス初期セットアップ
+ cy.request('POST', '/api/admin/accounts/create', {
+ username: 'admin',
+ password: 'pass',
+ }).as('setup');
+
+ cy.get('@setup').then(() => {
+ // ユーザー作成
+ cy.request('POST', '/api/signup', {
+ username: 'alice',
+ password: 'alice1234',
+ }).as('signup');
+ });
- cy.get('[data-cy-signin-username] input').type('alice');
+ cy.get('@signup').then(() => {
+ cy.visit('/');
- // Enterキーでサインインできるかの確認も兼ねる
- cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
- //#endregion
+ cy.intercept('POST', '/api/signin').as('signin');
- cy.get('[data-cy-open-post-form]').click();
+ cy.get('[data-cy-signin]').click();
+ cy.get('[data-cy-signin-username] input').type('alice');
+ cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
- cy.get('[data-cy-post-form-text]').type('Hello, Misskey!');
+ cy.wait('@signin').as('signinEnd');
+ });
- cy.get('[data-cy-open-post-form-submit]').click();
+ cy.get('@signinEnd').then(() => {
+ cy.get('[data-cy-open-post-form]').click();
+ cy.get('[data-cy-post-form-text]').type('Hello, Misskey!');
+ cy.get('[data-cy-open-post-form-submit]').click();
- // TODO: 投稿した文字列が画面内にあるか(=タイムラインに流れてきたか)のテスト
+ cy.contains('Hello, Misskey!');
+ });
});
+
+ it('suspend', function() {
+ cy.request('POST', '/api/admin/accounts/create', {
+ username: 'admin',
+ password: 'pass',
+ }).its('body').as('admin');
+
+ cy.request('POST', '/api/signup', {
+ username: 'alice',
+ password: 'pass',
+ }).its('body').as('alice');
+
+ cy.then(() => {
+ cy.request('POST', '/api/admin/suspend-user', {
+ i: this.admin.token,
+ userId: this.alice.id,
+ });
+
+ cy.visit('/');
+
+ cy.get('[data-cy-signin]').click();
+ cy.get('[data-cy-signin-username] input').type('alice');
+ cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
+
+ cy.contains('アカウントが凍結されています');
+ });
+ });
});
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index b9623ef0d0..2c0663cf87 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -529,6 +529,8 @@ removeAllFollowing: "フォローを全解除"
removeAllFollowingDescription: "{host}からのフォローをすべて解除します。そのインスタンスがもう存在しなくなった場合などに実行してください。"
userSuspended: "このユーザーは凍結されています。"
userSilenced: "このユーザーはサイレンスされています。"
+yourAccountSuspendedTitle: "アカウントが凍結されています"
+yourAccountSuspendedDescription: "このアカウントは、サーバーの利用規約に違反したなどの理由により、凍結されています。詳細については管理者までお問い合わせください。新しいアカウントを作らないでください。"
menu: "メニュー"
divider: "分割線"
addItem: "項目を追加"
diff --git a/src/client/account.ts b/src/client/account.ts
index e469bae5a2..6e26ac1f7d 100644
--- a/src/client/account.ts
+++ b/src/client/account.ts
@@ -3,6 +3,7 @@ import { reactive } from 'vue';
import { apiUrl } from '@client/config';
import { waiting } from '@client/os';
import { unisonReload, reloadChannel } from '@client/scripts/unison-reload';
+import { showSuspendedDialog } from './scripts/show-suspended-dialog';
// TODO: 他のタブと永続化されたstateを同期
@@ -82,17 +83,20 @@ function fetchAccount(token): Promise {
i: token
})
})
+ .then(res => res.json())
.then(res => {
- // When failed to authenticate user
- if (res.status !== 200 && res.status < 500) {
- return signout();
+ if (res.error) {
+ if (res.error.id === 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370') {
+ showSuspendedDialog().then(() => {
+ signout();
+ });
+ } else {
+ signout();
+ }
+ } else {
+ res.token = token;
+ done(res);
}
-
- // Parse response
- res.json().then(i => {
- i.token = token;
- done(i);
- });
})
.catch(fail);
});
diff --git a/src/client/components/signin.vue b/src/client/components/signin.vue
index c051288d0a..69f527b7d6 100755
--- a/src/client/components/signin.vue
+++ b/src/client/components/signin.vue
@@ -54,6 +54,7 @@ import { apiUrl, host } from '@client/config';
import { byteify, hexify } from '@client/scripts/2fa';
import * as os from '@client/os';
import { login } from '@client/account';
+import { showSuspendedDialog } from '../scripts/show-suspended-dialog';
export default defineComponent({
components: {
@@ -169,15 +170,7 @@ export default defineComponent({
this.signing = false;
this.challengeData = res;
return this.queryKey();
- }).catch(() => {
- os.dialog({
- type: 'error',
- text: this.$ts.signinFailed
- });
- this.challengeData = null;
- this.totpLogin = false;
- this.signing = false;
- });
+ }).catch(this.loginFailed);
} else {
this.totpLogin = true;
this.signing = false;
@@ -190,14 +183,36 @@ export default defineComponent({
}).then(res => {
this.$emit('login', res);
this.onLogin(res);
- }).catch(() => {
+ }).catch(this.loginFailed);
+ }
+ },
+
+ loginFailed(err) {
+ switch (err.id) {
+ case '6cc579cc-885d-43d8-95c2-b8c7fc963280': {
os.dialog({
type: 'error',
- text: this.$ts.loginFailed
+ title: this.$ts.loginFailed,
+ text: this.$ts.noSuchUser
});
- this.signing = false;
- });
+ break;
+ }
+ case 'e03a5f46-d309-4865-9b69-56282d94e1eb': {
+ showSuspendedDialog();
+ break;
+ }
+ default: {
+ os.dialog({
+ type: 'error',
+ title: this.$ts.loginFailed,
+ text: JSON.stringify(err)
+ });
+ }
}
+
+ this.challengeData = null;
+ this.totpLogin = false;
+ this.signing = false;
},
resetPassword() {
diff --git a/src/client/scripts/show-suspended-dialog.ts b/src/client/scripts/show-suspended-dialog.ts
new file mode 100644
index 0000000000..dde829cdae
--- /dev/null
+++ b/src/client/scripts/show-suspended-dialog.ts
@@ -0,0 +1,10 @@
+import * as os from '@client/os';
+import { i18n } from '@client/i18n';
+
+export function showSuspendedDialog() {
+ return os.dialog({
+ type: 'error',
+ title: i18n.locale.yourAccountSuspendedTitle,
+ text: i18n.locale.yourAccountSuspendedDescription
+ });
+}
diff --git a/src/server/api/endpoints/reset-db.ts b/src/server/api/endpoints/reset-db.ts
index f430869302..f0a9dae4ff 100644
--- a/src/server/api/endpoints/reset-db.ts
+++ b/src/server/api/endpoints/reset-db.ts
@@ -18,4 +18,6 @@ export default define(meta, async (ps, user) => {
if (process.env.NODE_ENV !== 'test') throw 'NODE_ENV is not a test';
await resetDb();
+
+ await new Promise(resolve => setTimeout(resolve, 1000));
});
diff --git a/src/server/api/private/signin.ts b/src/server/api/private/signin.ts
index fff1037ff9..83c3dfee94 100644
--- a/src/server/api/private/signin.ts
+++ b/src/server/api/private/signin.ts
@@ -18,6 +18,11 @@ export default async (ctx: Koa.Context) => {
const password = body['password'];
const token = body['token'];
+ function error(status: number, error: { id: string }) {
+ ctx.status = status;
+ ctx.body = { error };
+ }
+
if (typeof username != 'string') {
ctx.status = 400;
return;
@@ -40,15 +45,15 @@ export default async (ctx: Koa.Context) => {
}) as ILocalUser;
if (user == null) {
- ctx.throw(404, {
- error: 'user not found'
+ error(404, {
+ id: '6cc579cc-885d-43d8-95c2-b8c7fc963280',
});
return;
}
if (user.isSuspended) {
- ctx.throw(403, {
- error: 'user is suspended'
+ error(403, {
+ id: 'e03a5f46-d309-4865-9b69-56282d94e1eb',
});
return;
}
@@ -58,7 +63,7 @@ export default async (ctx: Koa.Context) => {
// Compare password
const same = await bcrypt.compare(password, profile.password!);
- async function fail(status?: number, failure?: { error: string }) {
+ async function fail(status?: number, failure?: { id: string }) {
// Append signin history
await Signins.insert({
id: genId(),
@@ -69,7 +74,7 @@ export default async (ctx: Koa.Context) => {
success: false
});
- ctx.throw(status || 500, failure || { error: 'someting happened' });
+ error(status || 500, failure || { id: '4e30e80c-e338-45a0-8c8f-44455efa3b76' });
}
if (!profile.twoFactorEnabled) {
@@ -78,7 +83,7 @@ export default async (ctx: Koa.Context) => {
return;
} else {
await fail(403, {
- error: 'incorrect password'
+ id: '932c904e-9460-45b7-9ce6-7ed33be7eb2c'
});
return;
}
@@ -87,7 +92,7 @@ export default async (ctx: Koa.Context) => {
if (token) {
if (!same) {
await fail(403, {
- error: 'incorrect password'
+ id: '932c904e-9460-45b7-9ce6-7ed33be7eb2c'
});
return;
}
@@ -104,14 +109,14 @@ export default async (ctx: Koa.Context) => {
return;
} else {
await fail(403, {
- error: 'invalid token'
+ id: 'cdf1235b-ac71-46d4-a3a6-84ccce48df6f'
});
return;
}
} else if (body.credentialId) {
if (!same && !profile.usePasswordLessLogin) {
await fail(403, {
- error: 'incorrect password'
+ id: '932c904e-9460-45b7-9ce6-7ed33be7eb2c'
});
return;
}
@@ -127,7 +132,7 @@ export default async (ctx: Koa.Context) => {
if (!challenge) {
await fail(403, {
- error: 'non-existent challenge'
+ id: '2715a88a-2125-4013-932f-aa6fe72792da'
});
return;
}
@@ -139,7 +144,7 @@ export default async (ctx: Koa.Context) => {
if (new Date().getTime() - challenge.createdAt.getTime() >= 5 * 60 * 1000) {
await fail(403, {
- error: 'non-existent challenge'
+ id: '2715a88a-2125-4013-932f-aa6fe72792da'
});
return;
}
@@ -155,7 +160,7 @@ export default async (ctx: Koa.Context) => {
if (!securityKey) {
await fail(403, {
- error: 'invalid credentialId'
+ id: '66269679-aeaf-4474-862b-eb761197e046'
});
return;
}
@@ -174,14 +179,14 @@ export default async (ctx: Koa.Context) => {
return;
} else {
await fail(403, {
- error: 'invalid challenge data'
+ id: '93b86c4b-72f9-40eb-9815-798928603d1e'
});
return;
}
} else {
if (!same && !profile.usePasswordLessLogin) {
await fail(403, {
- error: 'incorrect password'
+ id: '932c904e-9460-45b7-9ce6-7ed33be7eb2c'
});
return;
}
@@ -192,7 +197,7 @@ export default async (ctx: Koa.Context) => {
if (keys.length === 0) {
await fail(403, {
- error: 'no keys found'
+ id: 'f27fd449-9af4-4841-9249-1f989b9fa4a4'
});
return;
}
--
cgit v1.2.3-freya
From 90bf976fe26965280e6b0c90bfe8a55ea30ab0d7 Mon Sep 17 00:00:00 2001
From: tamaina
Date: Mon, 20 Sep 2021 22:14:49 +0900
Subject: enhance:
ノートヘッダーにflex-shrinkを設定し、Acctを優先的に縮小して見栄えをよくするように
(#7752)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* MAKE NOTE HEADER FLEX AGAIN
* span => div
* remove submodules
---
src/client/components/note-header.vue | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
(limited to 'src/client')
diff --git a/src/client/components/note-header.vue b/src/client/components/note-header.vue
index 7758dea3ae..80bfea9b07 100644
--- a/src/client/components/note-header.vue
+++ b/src/client/components/note-header.vue
@@ -3,10 +3,10 @@
- bot
-
-
-
+
+
@@ -55,6 +55,7 @@ export default defineComponent({
white-space: nowrap;
> .name {
+ flex-shrink: 1;
display: block;
margin: 0 .5em 0 0;
padding: 0;
@@ -81,17 +82,20 @@ export default defineComponent({
> .admin,
> .moderator {
+ flex-shrink: 0;
margin-right: 0.5em;
color: var(--badge);
}
> .username {
+ flex-shrink: 9999999;
margin: 0 .5em 0 0;
overflow: hidden;
text-overflow: ellipsis;
}
> .info {
+ flex-shrink: 0;
margin-left: auto;
font-size: 0.9em;
--
cgit v1.2.3-freya
From 78f95b59105906bffee7e7d282b801ef6a79bb53 Mon Sep 17 00:00:00 2001
From: syuilo
Date: Tue, 21 Sep 2021 02:01:25 +0900
Subject: :art:
---
src/client/themes/_dark.json5 | 1 +
src/client/themes/_light.json5 | 1 +
src/client/ui/_common_/sidebar.vue | 82 +++++++++++++++++++++++++++++++++-----
3 files changed, 74 insertions(+), 10 deletions(-)
(limited to 'src/client')
diff --git a/src/client/themes/_dark.json5 b/src/client/themes/_dark.json5
index b4553ee812..e1d5779a80 100644
--- a/src/client/themes/_dark.json5
+++ b/src/client/themes/_dark.json5
@@ -12,6 +12,7 @@
accent: '#86b300',
accentDarken: ':darken<10<@accent',
accentLighten: ':lighten<10<@accent',
+ accentedBg: ':alpha<0.15<@accent',
focus: ':alpha<0.3<@accent',
bg: '#000',
acrylicBg: ':alpha<0.5<@bg',
diff --git a/src/client/themes/_light.json5 b/src/client/themes/_light.json5
index 104f5a85af..87895e6406 100644
--- a/src/client/themes/_light.json5
+++ b/src/client/themes/_light.json5
@@ -12,6 +12,7 @@
accent: '#86b300',
accentDarken: ':darken<10<@accent',
accentLighten: ':lighten<10<@accent',
+ accentedBg: ':alpha<0.15<@accent',
focus: ':alpha<0.3<@accent',
bg: '#fff',
acrylicBg: ':alpha<0.5<@bg',
diff --git a/src/client/ui/_common_/sidebar.vue b/src/client/ui/_common_/sidebar.vue
index 333d0ac392..87002c3e70 100644
--- a/src/client/ui/_common_/sidebar.vue
+++ b/src/client/ui/_common_/sidebar.vue
@@ -263,22 +263,37 @@ export default defineComponent({
> .item {
padding-left: 0;
+ padding: 10px 0;
width: 100%;
text-align: center;
font-size: $ui-font-size * 1.1;
- line-height: 3.7rem;
+ line-height: initial;
> i,
> .avatar {
- margin-right: 0;
+ display: block;
+ margin: 0 auto;
}
> i {
- left: 10px;
+ opacity: 0.7;
}
> .text {
- display: none;
+ display: inline-block;
+ font-size: 0.5em;
+ line-height: initial;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ max-width: 100%;
+ opacity: 0.7;
+ }
+
+ &:hover, &.active {
+ > i, > .text {
+ opacity: 1;
+ }
}
&:first-child {
@@ -317,7 +332,7 @@ export default defineComponent({
background: var(--navBg);
> .divider {
- margin: 16px 0;
+ margin: 16px 16px;
border-top: solid 0.5px var(--divider);
}
@@ -326,7 +341,7 @@ export default defineComponent({
display: block;
padding-left: 24px;
font-size: $ui-font-size;
- line-height: 3rem;
+ line-height: 2.85rem;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
@@ -336,6 +351,7 @@ export default defineComponent({
color: var(--navFg);
> i {
+ position: relative;
width: 32px;
}
@@ -359,6 +375,11 @@ export default defineComponent({
animation: blink 1s infinite;
}
+ > .text {
+ position: relative;
+ font-size: 0.9em;
+ }
+
&:hover {
text-decoration: none;
color: var(--navHoverFg);
@@ -368,6 +389,23 @@ export default defineComponent({
color: var(--navActive);
}
+ &:hover, &.active {
+ &:before {
+ content: "";
+ display: block;
+ width: calc(100% - 20px);
+ height: 100%;
+ margin: auto;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ border-radius: 8px;
+ background: var(--accentedBg);
+ }
+ }
+
&:first-child, &:last-child {
position: sticky;
z-index: 1;
@@ -380,14 +418,38 @@ export default defineComponent({
&:first-child {
top: 0;
- margin-bottom: 16px;
- border-bottom: solid 0.5px var(--divider);
+
+ &:hover, &.active {
+ &:before {
+ content: none;
+ }
+ }
}
&:last-child {
bottom: 0;
- margin-top: 16px;
- border-top: solid 0.5px var(--divider);
+ color: var(--fgOnAccent);
+
+ &:before {
+ content: "";
+ display: block;
+ width: calc(100% - 20px);
+ height: calc(100% - 20px);
+ margin: auto;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ border-radius: 999px;
+ background: var(--accent);
+ }
+
+ &:hover, &.active {
+ &:before {
+ background: var(--accentLighten);
+ }
+ }
}
}
}
--
cgit v1.2.3-freya
From 85950f17fa7f80d3a33221b7f5105540c1197a51 Mon Sep 17 00:00:00 2001
From: syuilo
Date: Tue, 21 Sep 2021 04:09:28 +0900
Subject: :art:
---
src/client/pages/emojis.category.vue | 6 +++---
src/client/pages/emojis.vue | 10 ++++++++--
src/client/ui/_common_/sidebar.vue | 2 +-
src/client/ui/universal.vue | 4 ++--
4 files changed, 14 insertions(+), 8 deletions(-)
(limited to 'src/client')
diff --git a/src/client/pages/emojis.category.vue b/src/client/pages/emojis.category.vue
index 0c24b06d16..091c3f20a9 100644
--- a/src/client/pages/emojis.category.vue
+++ b/src/client/pages/emojis.category.vue
@@ -108,12 +108,12 @@ export default defineComponent({
margin: 8px 8px 0 0;
padding: 4px 8px;
font-size: 0.9em;
- background: var(--panel);
- border: solid 0.5px var(--divider);
+ background: var(--accentedBg);
border-radius: 5px;
&.active {
- border-color: var(--accent);
+ background: var(--accent);
+ color: var(--fgOnAccent);
}
}
}
diff --git a/src/client/pages/emojis.vue b/src/client/pages/emojis.vue
index c1f87047d3..8918de2338 100644
--- a/src/client/pages/emojis.vue
+++ b/src/client/pages/emojis.vue
@@ -1,5 +1,7 @@
-
+
Date: Tue, 21 Sep 2021 04:13:54 +0900
Subject: :art:
---
src/client/ui/_common_/sidebar.vue | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
(limited to 'src/client')
diff --git a/src/client/ui/_common_/sidebar.vue b/src/client/ui/_common_/sidebar.vue
index 6ebbd2d862..43b64d133e 100644
--- a/src/client/ui/_common_/sidebar.vue
+++ b/src/client/ui/_common_/sidebar.vue
@@ -11,28 +11,28 @@
+ bot
+
+
+
+
-
diff --git a/src/client/ui/_common_/sidebar.vue b/src/client/ui/_common_/sidebar.vue
index 87002c3e70..6ebbd2d862 100644
--- a/src/client/ui/_common_/sidebar.vue
+++ b/src/client/ui/_common_/sidebar.vue
@@ -393,7 +393,7 @@ export default defineComponent({
&:before {
content: "";
display: block;
- width: calc(100% - 20px);
+ width: calc(100% - 24px);
height: 100%;
margin: auto;
position: absolute;
diff --git a/src/client/ui/universal.vue b/src/client/ui/universal.vue
index cc754cba70..ec9254b697 100644
--- a/src/client/ui/universal.vue
+++ b/src/client/ui/universal.vue
@@ -312,8 +312,8 @@ export default defineComponent({
> .widgets {
padding: 0 var(--margin);
- //border-left: solid 0.5px var(--divider);
- background: var(--navBg);
+ border-left: solid 0.5px var(--divider);
+ background: var(--bg);
@media (max-width: $widgets-hide-threshold) {
display: none;
--
cgit v1.2.3-freya
From b35ca3b739e68c42c94eedabeda6976bfca2a6a3 Mon Sep 17 00:00:00 2001
From: syuilo
+
{{ $ts._mfm.sparkle }}
+
+
+
+
+ MFM
+
+