Compare commits

..

28 Commits

Author SHA1 Message Date
syuilo
2fcc3bb1ea 2.37.4 2018-06-12 02:19:00 +09:00
syuilo
2e680c3d1e Fix bug 2018-06-12 02:18:29 +09:00
syuilo
af0a0ef41b Merge branch 'master' of https://github.com/syuilo/misskey 2018-06-12 02:03:26 +09:00
syuilo
bbfccb0bbf 🎨 2018-06-12 02:03:18 +09:00
syuilo
c89eb5d69f Merge pull request #1705 from syuilo/l10n_master
New Crowdin translations
2018-06-12 02:03:06 +09:00
syuilo
ebde84214e Improve hashtag trend detection 2018-06-12 02:00:05 +09:00
syuilo
03fbae7b6d 変数調整 2018-06-12 01:51:51 +09:00
syuilo
f90e9596d4 Fix bug 2018-06-12 01:48:29 +09:00
syuilo
944f9524e2 Fix bug 2018-06-12 01:45:58 +09:00
syuilo
c61050244e 変数調整 2018-06-12 01:43:56 +09:00
syuilo
90337adbbc Improve hashtag trend detection 2018-06-12 01:41:17 +09:00
syuilo
7b67e41c5b New translations ja.yml (Polish) 2018-06-11 19:22:16 +09:00
syuilo
91db24fcfc 2.37.3 2018-06-11 14:16:46 +09:00
syuilo
bb53db905f ✌️ 2018-06-11 14:16:21 +09:00
syuilo
0e9a1efe46 Merge pull request #1704 from syuilo/l10n_master
New Crowdin translations
2018-06-11 14:11:33 +09:00
syuilo
289cd3e200 New translations ja.yml (English) 2018-06-11 14:10:47 +09:00
syuilo
e0f847e539 ✌️ 2018-06-11 14:06:23 +09:00
syuilo
c2842b486e New translations ja.yml (Portuguese) 2018-06-11 13:51:15 +09:00
syuilo
7235ade42f New translations ja.yml (Korean) 2018-06-11 13:51:13 +09:00
syuilo
850be2df1d New translations ja.yml (Polish) 2018-06-11 13:51:11 +09:00
syuilo
d504501440 New translations ja.yml (Chinese Simplified) 2018-06-11 13:51:09 +09:00
syuilo
208392f12c New translations ja.yml (Italian) 2018-06-11 13:51:07 +09:00
syuilo
0fe036c640 New translations ja.yml (Russian) 2018-06-11 13:51:05 +09:00
syuilo
a40c41f0b0 New translations ja.yml (English) 2018-06-11 13:51:03 +09:00
syuilo
4affa5b710 New translations ja.yml (Spanish) 2018-06-11 13:51:01 +09:00
syuilo
4eb574d991 New translations ja.yml (German) 2018-06-11 13:50:59 +09:00
syuilo
2c1577ea24 New translations ja.yml (French) 2018-06-11 13:50:56 +09:00
syuilo
b87e7e50b6 Clean up 2018-06-11 13:49:53 +09:00
14 changed files with 81 additions and 14 deletions

View File

@@ -227,6 +227,7 @@ common/views/widgets/posts-monitor.vue:
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "Serverinformationen" title: "Serverinformationen"
toggle: "Sicht umschalten" toggle: "Sicht umschalten"

View File

@@ -227,6 +227,7 @@ common/views/widgets/posts-monitor.vue:
toggle: "Toggle views" toggle: "Toggle views"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "Hashtags" title: "Hashtags"
count: "{} users mentioned"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "Server info" title: "Server info"
toggle: "Toggle views" toggle: "Toggle views"

View File

@@ -227,6 +227,7 @@ common/views/widgets/posts-monitor.vue:
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"

View File

@@ -227,6 +227,7 @@ common/views/widgets/posts-monitor.vue:
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "Info sur le serveur" title: "Info sur le serveur"
toggle: "Afficher les vues" toggle: "Afficher les vues"

View File

@@ -227,6 +227,7 @@ common/views/widgets/posts-monitor.vue:
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"

View File

@@ -227,6 +227,7 @@ common/views/widgets/posts-monitor.vue:
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"

View File

@@ -70,7 +70,7 @@ common:
donation: "Dotacje" donation: "Dotacje"
nav: "Nawigacja" nav: "Nawigacja"
tips: "Wskazówki" tips: "Wskazówki"
hashtags: "ハッシュタグ" hashtags: "Hashtagi"
deck: deck:
widgets: "Widżety" widgets: "Widżety"
home: "Strona główna" home: "Strona główna"
@@ -226,7 +226,8 @@ common/views/widgets/posts-monitor.vue:
title: "Wykres wpisów" title: "Wykres wpisów"
toggle: "Przełącz widok" toggle: "Przełącz widok"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "Hashtagi"
count: "Wspomniany przez {} użytkowników"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "Informacje o serwerze" title: "Informacje o serwerze"
toggle: "Przełącz widok" toggle: "Przełącz widok"

View File

@@ -227,6 +227,7 @@ common/views/widgets/posts-monitor.vue:
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"

View File

@@ -227,6 +227,7 @@ common/views/widgets/posts-monitor.vue:
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"

View File

@@ -227,6 +227,7 @@ common/views/widgets/posts-monitor.vue:
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"

View File

@@ -1,8 +1,8 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "2.37.2", "version": "2.37.4",
"clientVersion": "1.0.6437", "clientVersion": "1.0.6465",
"codename": "nighthike", "codename": "nighthike",
"main": "./built/index.js", "main": "./built/index.js",
"private": true, "private": true,

View File

@@ -49,7 +49,8 @@ export default Vue.extend({
polylinePoints: '', polylinePoints: '',
polygonPoints: '', polygonPoints: '',
headX: null, headX: null,
headY: null headY: null,
clock: null
}; };
}, },
watch: { watch: {
@@ -59,6 +60,12 @@ export default Vue.extend({
}, },
created() { created() {
this.draw(); this.draw();
// Vueが何故かWatchを発動させない場合があるので
this.clock = setInterval(this.draw, 1000);
},
beforeDestroy() {
clearInterval(this.clock);
}, },
methods: { methods: {
draw() { draw() {

View File

@@ -5,15 +5,15 @@
<div class="mkw-hashtags--body" :data-mobile="platform == 'mobile'"> <div class="mkw-hashtags--body" :data-mobile="platform == 'mobile'">
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p> <p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
<div v-else> <transition-group v-else tag="div" name="chart">
<div v-for="stat in stats" :key="stat.tag"> <div v-for="stat in stats" :key="stat.tag">
<div class="tag"> <div class="tag">
<router-link :to="`/tags/${ stat.tag }`">#{{ stat.tag }}</router-link> <router-link :to="`/tags/${ stat.tag }`" :title="stat.tag">#{{ stat.tag }}</router-link>
<p>{{ '%i18n:@count%'.replace('{}', stat.usersCount) }}</p> <p>{{ '%i18n:@count%'.replace('{}', stat.usersCount) }}</p>
</div> </div>
<x-chart class="chart" :src="stat.chart"/> <x-chart class="chart" :src="stat.chart"/>
</div> </div>
</div> </transition-group>
</div> </div>
</mk-widget-container> </mk-widget-container>
</div> </div>
@@ -41,7 +41,7 @@ export default define({
}, },
mounted() { mounted() {
this.fetch(); this.fetch();
this.clock = setInterval(this.fetch, 1000 * 60 * 10); this.clock = setInterval(this.fetch, 1000 * 60);
}, },
beforeDestroy() { beforeDestroy() {
clearInterval(this.clock); clearInterval(this.clock);
@@ -74,6 +74,14 @@ root(isDark)
margin-right 4px margin-right 4px
> div > div
.chart-enter
.chart-leave-to
opacity 0
transform translateY(-30px)
> *
transition transform .3s ease, opacity .3s ease
> div > div
display flex display flex
align-items center align-items center
@@ -84,10 +92,16 @@ root(isDark)
> .tag > .tag
flex 1 flex 1
overflow hidden
font-size 14px font-size 14px
color isDark ? #9baec8 : #65727b color isDark ? #9baec8 : #65727b
> a > a
display block
width 100%
white-space nowrap
overflow hidden
text-overflow ellipsis
color inherit color inherit
> p > p

View File

@@ -1,13 +1,24 @@
import Note from '../../../../models/note'; import Note from '../../../../models/note';
/*
トレンドに載るためには「『直近a分間のユニーク投稿数が今からa分前今からb分前の間のユニーク投稿数のn倍以上』のハッシュタグの上位5位以内に入る」ことが必要
ユニーク投稿数とはそのハッシュタグと投稿ユーザーのペアのカウントで、例えば同じユーザーが複数回同じハッシュタグを投稿してもそのハッシュタグのユニーク投稿数は1とカウントされる
*/
const rangeA = 1000 * 60 * 30; // 30分
const rangeB = 1000 * 60 * 120; // 2時間
const coefficient = 1.5; // 「n倍」の部分
const requiredUsers = 3; // 最低何人がそのタグを投稿している必要があるか
/** /**
* Get trends of hashtags * Get trends of hashtags
*/ */
module.exports = (params, user) => new Promise(async (res, rej) => { module.exports = () => new Promise(async (res, rej) => {
//#region 1. 直近Aの内に投稿されたハッシュタグ(とユーザーのペア)を集計
const data = await Note.aggregate([{ const data = await Note.aggregate([{
$match: { $match: {
createdAt: { createdAt: {
$gt: new Date(Date.now() - 1000 * 60 * 60) $gt: new Date(Date.now() - rangeA)
}, },
tags: { tags: {
$exists: true, $exists: true,
@@ -26,13 +37,15 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
userId: any; userId: any;
} }
}>; }>;
//#endregion
if (data.length == 0) { if (data.length == 0) {
return res([]); return res([]);
} }
const tags = []; let tags = [];
// カウント
data.map(x => x._id).forEach(x => { data.map(x => x._id).forEach(x => {
const i = tags.findIndex(tag => tag.name == x.tags); const i = tags.findIndex(tag => tag.name == x.tags);
if (i != -1) { if (i != -1) {
@@ -45,11 +58,34 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
} }
}); });
const hots = tags // 最低要求投稿者数を下回るならカットする
tags = tags.filter(tag => tag.count >= requiredUsers);
//#region 2. 1で取得したそれぞれのタグについて、「直近a分間のユニーク投稿数が今からa分前今からb分前の間のユニーク投稿数のn倍以上」かどうかを判定する
const hotsPromises = tags.map(async tag => {
const passedCount = (await Note.distinct('userId', {
tags: tag.name,
createdAt: {
$lt: new Date(Date.now() - rangeA),
$gt: new Date(Date.now() - rangeB)
}
}) as any).length;
if (tag.count > (passedCount * coefficient)) {
return tag;
} else {
return null;
}
});
//#endregion
const hots = (await Promise.all(hotsPromises))
.filter(x => x != null)
.sort((a, b) => b.count - a.count) .sort((a, b) => b.count - a.count)
.map(tag => tag.name) .map(tag => tag.name)
.slice(0, 5); .slice(0, 5);
//#region 2で話題と判定されたタグそれぞれについて過去の投稿数グラフを取得する
const countPromises: Array<Promise<any[]>> = []; const countPromises: Array<Promise<any[]>> = [];
const range = 20; const range = 20;
@@ -58,7 +94,6 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
const interval = 1000 * 60 * 10; const interval = 1000 * 60 * 10;
for (let i = 0; i < range; i++) { for (let i = 0; i < range; i++) {
countPromises.push(Promise.all(hots.map(tag => Note.distinct('userId', { countPromises.push(Promise.all(hots.map(tag => Note.distinct('userId', {
tags: tag, tags: tag,
createdAt: { createdAt: {
@@ -76,6 +111,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
$gt: new Date(Date.now() - (interval * range)) $gt: new Date(Date.now() - (interval * range))
} }
}))); })));
//#endregion
const stats = hots.map((tag, i) => ({ const stats = hots.map((tag, i) => ({
tag, tag,