-
{{ $t('images') }}
-
-
-
+
+
+ {{ $t('images') }}
+
-
-
-
{{ $t('activity') }}
-
-
-
+
+
+ {{ $t('activity') }}
+
-
-
-
{{ $t('timeline') }}
+
+
+ {{ $t('timeline') }}
-
+
@@ -124,9 +118,6 @@ export default Vue.extend({
moreFetching: false,
withFiles: false,
images: [],
- showPinned: true,
- showImages: true,
- showActivity: true
};
},
@@ -314,18 +305,6 @@ export default Vue.extend({
source: this.$refs.menu,
user: this.user
});
- },
-
- toggleShowPinned() {
- this.showPinned = !this.showPinned;
- },
-
- toggleShowImages() {
- this.showImages = !this.showImages;
- },
-
- toggleShowActivity() {
- this.showActivity = !this.showActivity;
}
}
});
@@ -469,39 +448,18 @@ export default Vue.extend({
font-size 80%
opacity 0.7
- > *
- > p.caption
- margin 0
- padding 8px 16px
- font-size 12px
- color var(--text)
+ .sainvnaq
+ display grid
+ grid-template-columns 1fr 1fr 1fr
+ gap 8px
+ padding 16px
- & + .angle
- position absolute
- top 0
- right 8px
- padding 6px
- font-size 14px
- color var(--text)
-
- > .pinned
- > .notes
- background var(--face)
-
- > .images
- > div
- display grid
- grid-template-columns 1fr 1fr 1fr
- gap 8px
- padding 16px
- background var(--face)
-
- > *
- height 70px
- background-position center center
- background-size cover
- background-clip content-box
- border-radius 4px
+ > *
+ height 70px
+ background-position center center
+ background-size cover
+ background-clip content-box
+ border-radius 4px
> .activity
> div
diff --git a/src/client/app/mobile/script.ts b/src/client/app/mobile/script.ts
index f912c0d53..1feff3d5e 100644
--- a/src/client/app/mobile/script.ts
+++ b/src/client/app/mobile/script.ts
@@ -134,6 +134,7 @@ init((launch) => {
{ path: '/search', component: MkSearch },
{ path: '/tags/:tag', component: MkTag },
{ path: '/featured', name: 'featured', component: () => import('./views/pages/featured.vue').then(m => m.default) },
+ { path: '/explore', name: 'explore', component: () => import('./views/pages/explore.vue').then(m => m.default) },
{ path: '/share', component: MkShare },
{ path: '/games/reversi/:game?', name: 'reversi', component: MkReversi },
{ path: '/@:user', component: () => import('./views/pages/user.vue').then(m => m.default) },
diff --git a/src/client/app/mobile/views/components/ui-container.vue b/src/client/app/mobile/views/components/ui-container.vue
index 6254a97ea..2dcd83f58 100644
--- a/src/client/app/mobile/views/components/ui-container.vue
+++ b/src/client/app/mobile/views/components/ui-container.vue
@@ -3,6 +3,10 @@
+
@@ -21,7 +25,16 @@ export default Vue.extend({
naked: {
type: Boolean,
default: false
- }
+ },
+ bodyTogglable: {
+ type: Boolean,
+ default: false
+ },
+ },
+ data() {
+ return {
+ showBody: true
+ };
}
});
diff --git a/src/client/app/mobile/views/components/ui.nav.vue b/src/client/app/mobile/views/components/ui.nav.vue
index af2e3e4c6..16bde6030 100644
--- a/src/client/app/mobile/views/components/ui.nav.vue
+++ b/src/client/app/mobile/views/components/ui.nav.vue
@@ -20,6 +20,7 @@
{{ $t('@.messaging') }}
{{ $t('follow-requests') }}
{{ $t('@.featured-notes') }}
+
{{ $t('@.explore') }}
{{ $t('game') }}
@@ -51,7 +52,7 @@
import Vue from 'vue';
import i18n from '../../../i18n';
import { lang } from '../../../config';
-import { faNewspaper } from '@fortawesome/free-solid-svg-icons';
+import { faNewspaper, faHashtag } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({
i18n: i18n('mobile/views/components/ui.nav.vue'),
@@ -64,7 +65,7 @@ export default Vue.extend({
aboutUrl: `/docs/${lang}/about`,
announcements: [],
searching: false,
- faNewspaper
+ faNewspaper, faHashtag
};
},
diff --git a/src/client/app/mobile/views/pages/explore.vue b/src/client/app/mobile/views/pages/explore.vue
new file mode 100644
index 000000000..80b819472
--- /dev/null
+++ b/src/client/app/mobile/views/pages/explore.vue
@@ -0,0 +1,37 @@
+
+
+ {{ $t('@.explore') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/models/user.ts b/src/models/user.ts
index ce0d17a04..6cc44f371 100644
--- a/src/models/user.ts
+++ b/src/models/user.ts
@@ -15,6 +15,9 @@ import Emoji from './emoji';
const User = db.get('users');
+User.createIndex('createdAt');
+User.createIndex('updatedAt');
+User.createIndex('followersCount');
User.createIndex('username');
User.createIndex('usernameLower');
User.createIndex('host');
diff --git a/src/server/api/endpoints/users.ts b/src/server/api/endpoints/users.ts
index c0da46483..fa35235a1 100644
--- a/src/server/api/endpoints/users.ts
+++ b/src/server/api/endpoints/users.ts
@@ -27,6 +27,18 @@ export const meta = {
]),
},
+ state: {
+ validator: $.optional.str.or([
+ 'all',
+ 'admin',
+ 'moderator',
+ 'adminOrModerator',
+ 'verified',
+ 'alive'
+ ]),
+ default: 'all'
+ },
+
origin: {
validator: $.optional.str.or([
'combined',
@@ -72,10 +84,32 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
};
}
- const q =
+ const q = {
+ $and: []
+ } as any;
+
+ // state
+ q.$and.push(
+ ps.state == 'admin' ? { isAdmin: true } :
+ ps.state == 'moderator' ? { isModerator: true } :
+ ps.state == 'adminOrModerator' ? {
+ $or: [{
+ isAdmin: true
+ }, {
+ isModerator: true
+ }]
+ } :
+ ps.state == 'verified' ? { isVerified: true } :
+ ps.state == 'alive' ? { updatedAt: { $gt: new Date(Date.now() - (1000 * 60 * 60 * 24 * 5)) } } :
+ {}
+ );
+
+ // origin
+ q.$and.push(
ps.origin == 'local' ? { host: null } :
ps.origin == 'remote' ? { host: { $ne: null } } :
- {};
+ {}
+ );
const users = await User
.find(q, {