diff --git a/.eslintrc b/.eslintrc index 7a74d6ef9b..0943cb4b64 100644 --- a/.eslintrc +++ b/.eslintrc @@ -14,6 +14,7 @@ "vue/no-unused-vars": false, "vue/attributes-order": false, "vue/require-prop-types": false, + "vue/require-default-prop": false, "no-console": 0, "no-unused-vars": 0, "no-empty": 0 diff --git a/locales/en.yml b/locales/en.yml index 0a05393227..4ef12432be 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -370,6 +370,7 @@ desktop/views/components/ui.header.account.vue: profile: "Your profile" drive: "Drive" favorites: "Favorites" + lists: "Lists" customize: "Customize" settings: "Settings" signout: "Sign out" diff --git a/locales/fr.yml b/locales/fr.yml index e640c4883c..80b1ed13da 100644 --- a/locales/fr.yml +++ b/locales/fr.yml @@ -370,6 +370,7 @@ desktop/views/components/ui.header.account.vue: profile: "Votre profil" drive: "Drive" favorites: "Favorites" + lists: "リスト" customize: "Modifications" settings: "Réglages" signout: "Déconnexion" diff --git a/locales/ja.yml b/locales/ja.yml index 3d023281cd..e13348c407 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -370,6 +370,7 @@ desktop/views/components/ui.header.account.vue: profile: "プロフィール" drive: "ドライブ" favorites: "お気に入り" + lists: "リスト" customize: "カスタマイズ" settings: "設定" signout: "サインアウト" diff --git a/package.json b/package.json index 0a3026e17e..d37bbc040d 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "autwh": "0.1.0", "bcryptjs": "2.4.3", "bootstrap-vue": "2.0.0-rc.6", - "cafy": "3.2.1", + "cafy": "6.0.0", "chai": "4.1.2", "chai-http": "4.0.0", "chalk": "2.4.0", @@ -144,6 +144,7 @@ "koa-multer": "1.0.2", "koa-router": "7.4.0", "koa-send": "4.1.3", + "koa-slow": "^2.1.0", "kue": "0.11.6", "license-checker": "18.0.0", "loader-utils": "1.1.0", diff --git a/src/cafy-id.ts b/src/cafy-id.ts new file mode 100644 index 0000000000..3faf5cd996 --- /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 { + constructor(...args) { + super(...args); + + this.transform = v => { + if (isAnId(v) && !mongo.ObjectID.prototype.isPrototypeOf(v)) { + return new mongo.ObjectID(v); + } else { + return v; + } + }; + + this.pushValidator(v => { + if (!mongo.ObjectID.prototype.isPrototypeOf(v) && isNotAnId(v)) { + return new Error('must-be-an-id'); + } + return true; + }); + } +} diff --git a/src/client/app/common/mios.ts b/src/client/app/common/mios.ts index 463f763888..4e471cf96f 100644 --- a/src/client/app/common/mios.ts +++ b/src/client/app/common/mios.ts @@ -88,6 +88,7 @@ export default class MiOS extends EventEmitter { propsData: props }).$mount(); document.body.appendChild(w.$el); + return w; } /** diff --git a/src/client/app/common/scripts/streaming/user-list.ts b/src/client/app/common/scripts/streaming/user-list.ts new file mode 100644 index 0000000000..30a52b98dd --- /dev/null +++ b/src/client/app/common/scripts/streaming/user-list.ts @@ -0,0 +1,17 @@ +import Stream from './stream'; +import MiOS from '../../mios'; + +export class UserListStream extends Stream { + constructor(os: MiOS, me, listId) { + super(os, 'user-list', { + i: me.token, + listId + }); + + (this as any).on('_connected_', () => { + this.send({ + i: me.token + }); + }); + } +} diff --git a/src/client/app/desktop/api/update-banner.ts b/src/client/app/desktop/api/update-banner.ts index bc3f783e35..feb1c33103 100644 --- a/src/client/app/desktop/api/update-banner.ts +++ b/src/client/app/desktop/api/update-banner.ts @@ -95,7 +95,7 @@ export default (os: OS) => { multiple: false, title: '%fa:image%バナーにする画像を選択' }); - + return selectedFile .then(cropImage) .then(setBanner) diff --git a/src/client/app/desktop/script.ts b/src/client/app/desktop/script.ts index 3b0ed48cd0..2658a86b95 100644 --- a/src/client/app/desktop/script.ts +++ b/src/client/app/desktop/script.ts @@ -28,6 +28,7 @@ import MkUser from './views/pages/user/user.vue'; import MkFavorites from './views/pages/favorites.vue'; import MkSelectDrive from './views/pages/selectdrive.vue'; import MkDrive from './views/pages/drive.vue'; +import MkUserList from './views/pages/user-list.vue'; import MkHomeCustomize from './views/pages/home-customize.vue'; import MkMessagingRoom from './views/pages/messaging-room.vue'; import MkNote from './views/pages/note.vue'; @@ -55,6 +56,7 @@ init(async (launch) => { { path: '/i/messaging/:user', component: MkMessagingRoom }, { path: '/i/drive', component: MkDrive }, { path: '/i/drive/folder/:folder', component: MkDrive }, + { path: '/i/lists/:list', component: MkUserList }, { path: '/selectdrive', component: MkSelectDrive }, { path: '/search', component: MkSearch }, { path: '/othello', component: MkOthello }, diff --git a/src/client/app/desktop/views/components/follow-button.vue b/src/client/app/desktop/views/components/follow-button.vue index 30e8cab76f..60c6129f61 100644 --- a/src/client/app/desktop/views/components/follow-button.vue +++ b/src/client/app/desktop/views/components/follow-button.vue @@ -19,6 +19,7 @@ - > [data-fa] - display block - margin-bottom 16px - font-size 3em - color #ccc + diff --git a/src/client/app/desktop/views/components/timeline.vue b/src/client/app/desktop/views/components/timeline.vue index 8035510a14..f5f13cbd56 100644 --- a/src/client/app/desktop/views/components/timeline.vue +++ b/src/client/app/desktop/views/components/timeline.vue @@ -1,19 +1,23 @@ diff --git a/src/client/app/desktop/views/components/user-lists-window.vue b/src/client/app/desktop/views/components/user-lists-window.vue new file mode 100644 index 0000000000..d082610132 --- /dev/null +++ b/src/client/app/desktop/views/components/user-lists-window.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/src/client/app/desktop/views/components/users-list.vue b/src/client/app/desktop/views/components/users-list.vue index a08e76f573..e8f4c94d42 100644 --- a/src/client/app/desktop/views/components/users-list.vue +++ b/src/client/app/desktop/views/components/users-list.vue @@ -2,8 +2,8 @@
@@ -98,7 +98,7 @@ export default Vue.extend({ * pointer-events none - &[data-is-active] + &[data-active] font-weight bold color $theme-color border-color $theme-color diff --git a/src/client/app/desktop/views/components/widget-container.vue b/src/client/app/desktop/views/components/widget-container.vue index c3fac1399d..926d7702b9 100644 --- a/src/client/app/desktop/views/components/widget-container.vue +++ b/src/client/app/desktop/views/components/widget-container.vue @@ -58,7 +58,7 @@ root(isDark) box-shadow 0 1px rgba(0, 0, 0, 0.07) > [data-fa] - margin-right 4px + margin-right 6px &:empty display none diff --git a/src/client/app/desktop/views/pages/user-list.users.vue b/src/client/app/desktop/views/pages/user-list.users.vue new file mode 100644 index 0000000000..63070ed609 --- /dev/null +++ b/src/client/app/desktop/views/pages/user-list.users.vue @@ -0,0 +1,131 @@ + + + + + diff --git a/src/client/app/desktop/views/pages/user-list.vue b/src/client/app/desktop/views/pages/user-list.vue new file mode 100644 index 0000000000..2241b84e5e --- /dev/null +++ b/src/client/app/desktop/views/pages/user-list.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/client/app/desktop/views/pages/user/user.profile.vue b/src/client/app/desktop/views/pages/user/user.profile.vue index 774f300a38..64acbd86b3 100644 --- a/src/client/app/desktop/views/pages/user/user.profile.vue +++ b/src/client/app/desktop/views/pages/user/user.profile.vue @@ -3,15 +3,18 @@

%i18n:@follows-you%

-

- %i18n:@stalking% %i18n:@unstalk% - %i18n:@stalk% -

-

- %i18n:@muted% %i18n:@unmute% - %i18n:@mute% +

+ %i18n:@stalking% %fa:meh% %i18n:@unstalk% + %fa:user-secret% %i18n:@stalk%

+
+ + +
{{ user.description }}

%fa:birthday-cake%{{ user.profile.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ age }}歳)

@@ -32,6 +35,7 @@ import Vue from 'vue'; import * as age from 's-age'; import MkFollowingWindow from '../../components/following-window.vue'; import MkFollowersWindow from '../../components/followers-window.vue'; +import MkUserListsWindow from '../../components/user-lists-window.vue'; export default Vue.extend({ props: ['user'], @@ -91,6 +95,21 @@ export default Vue.extend({ }, () => { alert('error'); }); + }, + + list() { + const w = (this as any).os.new(MkUserListsWindow); + w.$once('choosen', async list => { + w.close(); + await (this as any).api('users/lists/push', { + listId: list.id, + userId: this.user.id + }); + (this as any).apis.dialog({ + title: 'Done!', + text: `${this.user.name}を${list.title}に追加しました。` + }); + }); } } }); @@ -107,11 +126,9 @@ export default Vue.extend({ > .friend-form padding 16px + text-align center border-top solid 1px #eee - > .mk-big-follow-button - width 100% - > .followed margin 12px 0 0 0 padding 0 @@ -122,6 +139,20 @@ export default Vue.extend({ background #eefaff border-radius 4px + > .stalk + margin 12px 0 0 0 + + > .action-form + padding 16px + text-align center + border-top solid 1px #eee + + > * + width 100% + + &:not(:last-child) + margin-bottom 12px + > .description padding 16px color #555 diff --git a/src/client/app/desktop/views/pages/user/user.timeline.vue b/src/client/app/desktop/views/pages/user/user.timeline.vue index 55d6072a9d..9c9840c190 100644 --- a/src/client/app/desktop/views/pages/user/user.timeline.vue +++ b/src/client/app/desktop/views/pages/user/user.timeline.vue @@ -1,42 +1,36 @@ - - diff --git a/src/client/app/mobile/views/components/user-list-timeline.vue b/src/client/app/mobile/views/components/user-list-timeline.vue new file mode 100644 index 0000000000..ee983a969c --- /dev/null +++ b/src/client/app/mobile/views/components/user-list-timeline.vue @@ -0,0 +1,93 @@ + + + diff --git a/src/client/app/mobile/views/components/user-timeline.vue b/src/client/app/mobile/views/components/user-timeline.vue index 40b3be035e..89ac4d2c66 100644 --- a/src/client/app/mobile/views/components/user-timeline.vue +++ b/src/client/app/mobile/views/components/user-timeline.vue @@ -1,17 +1,10 @@ @@ -19,49 +12,53 @@ + + diff --git a/src/client/app/mobile/views/pages/home.timeline.vue b/src/client/app/mobile/views/pages/home.timeline.vue new file mode 100644 index 0000000000..5f4bd6dcd8 --- /dev/null +++ b/src/client/app/mobile/views/pages/home.timeline.vue @@ -0,0 +1,149 @@ + + + diff --git a/src/client/app/mobile/views/pages/home.vue b/src/client/app/mobile/views/pages/home.vue index 3d94dd7ce6..92d34fa83b 100644 --- a/src/client/app/mobile/views/pages/home.vue +++ b/src/client/app/mobile/views/pages/home.vue @@ -1,59 +1,42 @@