From ffaec0b9712df9a5024c0883a154442f02b72a03 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 28 Aug 2017 23:47:43 +0900 Subject: #497 --- src/api/endpoints/i/regenerate_token.ts | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/api/endpoints/i/regenerate_token.ts (limited to 'src/api/endpoints/i') diff --git a/src/api/endpoints/i/regenerate_token.ts b/src/api/endpoints/i/regenerate_token.ts new file mode 100644 index 0000000000..ccebbc8101 --- /dev/null +++ b/src/api/endpoints/i/regenerate_token.ts @@ -0,0 +1,42 @@ +/** + * Module dependencies + */ +import $ from 'cafy'; +import * as bcrypt from 'bcryptjs'; +import User from '../../models/user'; +import event from '../../event'; +import generateUserToken from '../../common/generate-native-user-token'; + +/** + * Regenerate native token + * + * @param {any} params + * @param {any} user + * @return {Promise} + */ +module.exports = async (params, user) => new Promise(async (res, rej) => { + // Get 'password' parameter + const [password, passwordErr] = $(params.password).string().$; + if (passwordErr) return rej('invalid password param'); + + // Compare password + const same = bcrypt.compareSync(password, user.password); + + if (!same) { + return rej('incorrect password'); + } + + // Generate secret + const secret = generateUserToken(); + + await User.update(user._id, { + $set: { + token: secret + } + }); + + res(); + + // Publish i updated event + event(user._id, 'my_token_regenerated'); +}); -- cgit v1.2.3-freya From cdcd8e5c40197c807c69aea19899bc556c8b783b Mon Sep 17 00:00:00 2001 From: こぴなたみぽ Date: Mon, 28 Aug 2017 23:49:14 +0900 Subject: Update regenerate_token.ts --- src/api/endpoints/i/regenerate_token.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/api/endpoints/i') diff --git a/src/api/endpoints/i/regenerate_token.ts b/src/api/endpoints/i/regenerate_token.ts index ccebbc8101..f96d10ebfc 100644 --- a/src/api/endpoints/i/regenerate_token.ts +++ b/src/api/endpoints/i/regenerate_token.ts @@ -37,6 +37,6 @@ module.exports = async (params, user) => new Promise(async (res, rej) => { res(); - // Publish i updated event + // Publish event event(user._id, 'my_token_regenerated'); }); -- cgit v1.2.3-freya From 8f0e6a70cf22f1248b99bd3b300feed8b1b1efc8 Mon Sep 17 00:00:00 2001 From: syuilo Date: Tue, 29 Aug 2017 00:20:47 +0900 Subject: #364 --- CHANGELOG.md | 1 + locales/en.yml | 9 ++++++++ locales/ja.yml | 9 ++++++++ src/api/endpoints.ts | 4 ++++ src/api/endpoints/i/change_password.ts | 42 ++++++++++++++++++++++++++++++++++ src/web/app/desktop/tags/settings.tag | 38 ++++++++++++++++++++++++++++-- 6 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/api/endpoints/i/change_password.ts (limited to 'src/api/endpoints/i') diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d18b1b7f6..4e49f9ca49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ChangeLog unlereased ---------- * New: トークンを再生成できるように (#497) +* New: パスワードを変更する機能 (#364) 2461 (2017/08/28) ----------------- diff --git a/locales/en.yml b/locales/en.yml index 950180278d..a24b8725ae 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -208,6 +208,12 @@ desktop: settings: "Settings" signout: "Sign out" + mk-password-setting: + reset: "Change your password" + enter-current-password: "Enter the current password" + enter-new-password: "Enter the new password" + changed: "Password updated successfully" + mk-post-form: post-placeholder: "What's happening?" reply-placeholder: "Reply to this post..." @@ -239,6 +245,9 @@ desktop: prev: "Previous post" next: "Next post" + mk-settings: + password: "Password" + mk-timeline-post: reposted-by: "Reposted by {}" reply: "Reply" diff --git a/locales/ja.yml b/locales/ja.yml index 2655eb4846..88e0b76d82 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -208,6 +208,12 @@ desktop: settings: "設定" signout: "サインアウト" + mk-password-setting: + reset: "パスワードを変更する" + enter-current-password: "現在のパスワードを入力してください" + enter-new-password: "新しいパスワードを入力してください" + changed: "パスワードを変更しました" + mk-post-form: post-placeholder: "いまどうしてる?" reply-placeholder: "この投稿への返信..." @@ -239,6 +245,9 @@ desktop: prev: "前の投稿" next: "次の投稿" + mk-settings: + password: "パスワード" + mk-timeline-post: reposted-by: "{}がRepost" reply: "返信" diff --git a/src/api/endpoints.ts b/src/api/endpoints.ts index a658c9a42e..c6661533e8 100644 --- a/src/api/endpoints.ts +++ b/src/api/endpoints.ts @@ -159,6 +159,10 @@ const endpoints: Endpoint[] = [ }, kind: 'account-write' }, + { + name: 'i/change_password', + withCredential: true + }, { name: 'i/regenerate_token', withCredential: true diff --git a/src/api/endpoints/i/change_password.ts b/src/api/endpoints/i/change_password.ts new file mode 100644 index 0000000000..faceded29d --- /dev/null +++ b/src/api/endpoints/i/change_password.ts @@ -0,0 +1,42 @@ +/** + * Module dependencies + */ +import $ from 'cafy'; +import * as bcrypt from 'bcryptjs'; +import User from '../../models/user'; + +/** + * Change password + * + * @param {any} params + * @param {any} user + * @return {Promise} + */ +module.exports = async (params, user) => new Promise(async (res, rej) => { + // Get 'current_password' parameter + const [currentPassword, currentPasswordErr] = $(params.current_password).string().$; + if (currentPasswordErr) return rej('invalid current_password param'); + + // Get 'new_password' parameter + const [newPassword, newPasswordErr] = $(params.new_password).string().$; + if (newPasswordErr) return rej('invalid new_password param'); + + // Compare password + const same = bcrypt.compareSync(currentPassword, user.password); + + if (!same) { + return rej('incorrect password'); + } + + // Generate hash of password + const salt = bcrypt.genSaltSync(8); + const hash = bcrypt.hashSync(newPassword, salt); + + await User.update(user._id, { + $set: { + password: hash + } + }); + + res(); +}); diff --git a/src/web/app/desktop/tags/settings.tag b/src/web/app/desktop/tags/settings.tag index 7fc6acb4a8..80a42d6652 100644 --- a/src/web/app/desktop/tags/settings.tag +++ b/src/web/app/desktop/tags/settings.tag @@ -7,7 +7,7 @@

アプリ

Twitter

ログイン履歴

-

パスワード

+

%i18n:desktop.tags.mk-settings.password%

API

@@ -58,6 +58,11 @@ +
+

%i18n:desktop.tags.mk-settings.password%

+ +
+

API

@@ -236,8 +241,37 @@ passwordDialog('%i18n:desktop.tags.mk-api-info.regenerate-token%', password => { this.api('i/regenerate_token', { password: password - }) + }); }); }; + + + + + + -- cgit v1.2.3-freya From e7415dd42bf656a24d70c49776ff7c84a1838f9e Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 30 Aug 2017 17:31:39 +0900 Subject: Implement #746 --- CHANGELOG.md | 4 + locales/en.yml | 4 + locales/ja.yml | 4 + src/api/endpoints.ts | 4 + src/api/endpoints/i/pin.ts | 44 ++++++++++ src/api/serializers/user.ts | 43 ++++++---- src/web/app/common/tags/index.js | 1 + src/web/app/common/tags/post-menu.tag | 134 +++++++++++++++++++++++++++++++ src/web/app/desktop/tags/post-detail.tag | 23 ++++-- src/web/app/desktop/tags/timeline.tag | 21 +++-- src/web/app/mobile/tags/page/post.tag | 14 +++- src/web/app/mobile/tags/post-detail.tag | 54 +++++++------ src/web/app/mobile/tags/timeline.tag | 23 ++++-- src/web/app/mobile/tags/user.tag | 4 + 14 files changed, 316 insertions(+), 61 deletions(-) create mode 100644 src/api/endpoints/i/pin.ts create mode 100644 src/web/app/common/tags/post-menu.tag (limited to 'src/api/endpoints/i') diff --git a/CHANGELOG.md b/CHANGELOG.md index c64a8ea04d..2669bfee74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ChangeLog (Release Notes) ========================= 主に notable な changes を書いていきます +unreleased +---------- +* New: 投稿のピン留め (#746) + 2508 (2017/08/30) ----------------- * New: モバイル版のユーザーページのアクティビティチャートを変更 diff --git a/locales/en.yml b/locales/en.yml index 29a6a764d3..15d278c370 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -77,6 +77,10 @@ common: show-result: "Show result" voted: "Voted" + mk-post-menu: + pin: "Pin" + pinned: "Pinned" + mk-reaction-picker: choose-reaction: "Pick your reaction" diff --git a/locales/ja.yml b/locales/ja.yml index 21a07640d0..7ed4262f1c 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -77,6 +77,10 @@ common: show-result: "結果を見る" voted: "投票済み" + mk-post-menu: + pin: "ピン留め" + pinned: "ピン留めしました" + mk-reaction-picker: choose-reaction: "リアクションを選択" diff --git a/src/api/endpoints.ts b/src/api/endpoints.ts index c6661533e8..e5be68c096 100644 --- a/src/api/endpoints.ts +++ b/src/api/endpoints.ts @@ -167,6 +167,10 @@ const endpoints: Endpoint[] = [ name: 'i/regenerate_token', withCredential: true }, + { + name: 'i/pin', + kind: 'account-write' + }, { name: 'i/appdata/get', withCredential: true diff --git a/src/api/endpoints/i/pin.ts b/src/api/endpoints/i/pin.ts new file mode 100644 index 0000000000..a94950d22b --- /dev/null +++ b/src/api/endpoints/i/pin.ts @@ -0,0 +1,44 @@ +/** + * Module dependencies + */ +import $ from 'cafy'; +import User from '../../models/user'; +import Post from '../../models/post'; +import serialize from '../../serializers/user'; + +/** + * Pin post + * + * @param {any} params + * @param {any} user + * @return {Promise} + */ +module.exports = async (params, user) => new Promise(async (res, rej) => { + // Get 'post_id' parameter + const [postId, postIdErr] = $(params.post_id).id().$; + if (postIdErr) return rej('invalid post_id param'); + + // Fetch pinee + const post = await Post.findOne({ + _id: postId, + user_id: user._id + }); + + if (post === null) { + return rej('post not found'); + } + + await User.update(user._id, { + $set: { + pinned_post_id: post._id + } + }); + + // Serialize + const iObj = await serialize(user, user, { + detail: true + }); + + // Send response + res(iObj); +}); diff --git a/src/api/serializers/user.ts b/src/api/serializers/user.ts index bdbc749589..c9189d9034 100644 --- a/src/api/serializers/user.ts +++ b/src/api/serializers/user.ts @@ -4,6 +4,7 @@ import * as mongo from 'mongodb'; import deepcopy = require('deepcopy'); import User from '../models/user'; +import serializePost from './post'; import Following from '../models/following'; import getFriends from '../common/get-friends'; import config from '../../conf'; @@ -116,24 +117,32 @@ export default ( _user.is_followed = follow2 !== null; } - if (me && !me.equals(_user.id) && opts.detail) { - const myFollowingIds = await getFriends(me); - - // Get following you know count - const followingYouKnowCount = await Following.count({ - followee_id: { $in: myFollowingIds }, - follower_id: _user.id, - deleted_at: { $exists: false } - }); - _user.following_you_know_count = followingYouKnowCount; + if (opts.detail) { + if (_user.pinned_post_id) { + _user.pinned_post = await serializePost(_user.pinned_post_id, me, { + detail: true + }); + } - // Get followers you know count - const followersYouKnowCount = await Following.count({ - followee_id: _user.id, - follower_id: { $in: myFollowingIds }, - deleted_at: { $exists: false } - }); - _user.followers_you_know_count = followersYouKnowCount; + if (me && !me.equals(_user.id)) { + const myFollowingIds = await getFriends(me); + + // Get following you know count + const followingYouKnowCount = await Following.count({ + followee_id: { $in: myFollowingIds }, + follower_id: _user.id, + deleted_at: { $exists: false } + }); + _user.following_you_know_count = followingYouKnowCount; + + // Get followers you know count + const followersYouKnowCount = await Following.count({ + followee_id: _user.id, + follower_id: { $in: myFollowingIds }, + deleted_at: { $exists: false } + }); + _user.followers_you_know_count = followersYouKnowCount; + } } resolve(_user); diff --git a/src/web/app/common/tags/index.js b/src/web/app/common/tags/index.js index dd6ba75d7a..6e6081da9b 100644 --- a/src/web/app/common/tags/index.js +++ b/src/web/app/common/tags/index.js @@ -28,3 +28,4 @@ require('./reaction-picker.tag'); require('./reactions-viewer.tag'); require('./reaction-icon.tag'); require('./weekly-activity-chart.tag'); +require('./post-menu.tag'); diff --git a/src/web/app/common/tags/post-menu.tag b/src/web/app/common/tags/post-menu.tag new file mode 100644 index 0000000000..33895212bc --- /dev/null +++ b/src/web/app/common/tags/post-menu.tag @@ -0,0 +1,134 @@ + +
+
+ +
+ + +
diff --git a/src/web/app/desktop/tags/post-detail.tag b/src/web/app/desktop/tags/post-detail.tag index 7a90dccf39..58343482d0 100644 --- a/src/web/app/desktop/tags/post-detail.tag +++ b/src/web/app/desktop/tags/post-detail.tag @@ -43,16 +43,18 @@
- - - + -
@@ -315,6 +317,13 @@ }); }; + this.menu = () => { + riot.mount(document.body.appendChild(document.createElement('mk-post-menu')), { + source: this.refs.menuButton, + post: this.p + }); + }; + this.loadContext = () => { this.contextFetching = true; diff --git a/src/web/app/desktop/tags/timeline.tag b/src/web/app/desktop/tags/timeline.tag index bce27cd7f3..cd7ac7d207 100644 --- a/src/web/app/desktop/tags/timeline.tag +++ b/src/web/app/desktop/tags/timeline.tag @@ -128,16 +128,16 @@
- - - - - - + -
-
+
@@ -64,19 +66,14 @@ :scope display block overflow hidden - margin 8px auto + margin 0 auto padding 0 - max-width 500px - width calc(100% - 16px) + width 100% text-align left background #fff border-radius 8px box-shadow 0 0 0 1px rgba(0, 0, 0, 0.2) - @media (min-width 500px) - margin 16px auto - width calc(100% - 32px) - > .fetching padding 64px 0 @@ -269,6 +266,7 @@ this.mixin('api'); + this.compact = this.opts.compact; this.post = this.opts.post; this.isRepost = this.post.repost != null; this.p = this.isRepost ? this.post.repost : this.post; @@ -299,14 +297,16 @@ } // Get replies - this.api('posts/replies', { - post_id: this.p.id, - limit: 8 - }).then(replies => { - this.update({ - replies: replies + if (!this.compact) { + this.api('posts/replies', { + post_id: this.p.id, + limit: 8 + }).then(replies => { + this.update({ + replies: replies + }); }); - }); + } }); this.reply = () => { @@ -332,6 +332,14 @@ }); }; + this.menu = () => { + riot.mount(document.body.appendChild(document.createElement('mk-post-menu')), { + source: this.refs.menuButton, + post: this.p, + compact: true + }); + }; + this.loadContext = () => { this.contextFetching = true; diff --git a/src/web/app/mobile/tags/timeline.tag b/src/web/app/mobile/tags/timeline.tag index 43470d197e..d8df8b2663 100644 --- a/src/web/app/mobile/tags/timeline.tag +++ b/src/web/app/mobile/tags/timeline.tag @@ -181,14 +181,17 @@
- - - +
@@ -558,6 +561,14 @@ compact: true }); }; + + this.menu = () => { + riot.mount(document.body.appendChild(document.createElement('mk-post-menu')), { + source: this.refs.menuButton, + post: this.p, + compact: true + }); + }; diff --git a/src/web/app/mobile/tags/user.tag b/src/web/app/mobile/tags/user.tag index d85e3b51fd..0fe4055cf0 100644 --- a/src/web/app/mobile/tags/user.tag +++ b/src/web/app/mobile/tags/user.tag @@ -215,6 +215,7 @@ +

%i18n:mobile.tags.mk-user-overview.recent-posts%

@@ -240,6 +241,9 @@ max-width 600px margin 0 auto + > mk-post-detail + margin 0 0 8px 0 + > section background #eee border-radius 8px -- cgit v1.2.3-freya From 6a5c6280ffd3ffe820beb23294f1c2c1f5deb9cf Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 7 Oct 2017 03:36:46 +0900 Subject: :v: --- src/api/bot/core.ts | 88 ++++++++++++++++++++++++ src/api/bot/interfaces/line.ts | 37 ++++++++++ src/api/endpoints/i/appdata/set.ts | 2 +- src/api/models/user.ts | 3 + src/api/serializers/user.ts | 1 + src/api/server.ts | 2 + src/common/get-post-summary.js | 39 +++++++++++ src/config.ts | 3 + src/web/app/common/scripts/get-post-summary.js | 35 ---------- src/web/app/desktop/script.js | 2 +- src/web/app/desktop/tags/notifications.tag | 2 +- src/web/app/desktop/tags/pages/home.tag | 2 +- src/web/app/mobile/tags/notification-preview.tag | 2 +- src/web/app/mobile/tags/notification.tag | 2 +- src/web/app/mobile/tags/notifications.tag | 2 +- src/web/app/mobile/tags/page/home.tag | 2 +- src/web/app/mobile/tags/post-detail.tag | 2 +- src/web/app/mobile/tags/timeline.tag | 2 +- src/web/app/mobile/tags/user.tag | 2 +- tslint.json | 1 + 20 files changed, 185 insertions(+), 46 deletions(-) create mode 100644 src/api/bot/core.ts create mode 100644 src/api/bot/interfaces/line.ts create mode 100644 src/common/get-post-summary.js delete mode 100644 src/web/app/common/scripts/get-post-summary.js (limited to 'src/api/endpoints/i') diff --git a/src/api/bot/core.ts b/src/api/bot/core.ts new file mode 100644 index 0000000000..002ac1b06e --- /dev/null +++ b/src/api/bot/core.ts @@ -0,0 +1,88 @@ +import * as EventEmitter from 'events'; +import * as bcrypt from 'bcryptjs'; + +import User, { IUser } from '../models/user'; + +export default class BotCore extends EventEmitter { + public user: IUser; + + private context: Context = null; + + constructor(user: IUser) { + super(); + + this.user = user; + } + + public async q(query: string): Promise { + if (this.context != null) { + return await this.context.q(query); + } + + switch (query) { + case 'ping': + return 'PONG'; + case 'ログイン': + case 'サインイン': + this.context = new SigninContext(this); + return await this.context.greet(); + default: + return '?'; + } + } + + public setUser(user: IUser) { + this.user = user; + this.emit('set-user', user); + } +} + +abstract class Context { + protected core: BotCore; + + public abstract async greet(): Promise; + public abstract async q(query: string): Promise; + + constructor(core: BotCore) { + this.core = core; + } +} + +class SigninContext extends Context { + private temporaryUser: IUser; + + public async greet(): Promise { + return 'まずユーザー名を教えてください:'; + } + + public async q(query: string): Promise { + if (this.temporaryUser == null) { + // Fetch user + const user: IUser = await User.findOne({ + username_lower: query.toLowerCase() + }, { + fields: { + data: false, + profile: false + } + }); + + if (user === null) { + return `${query}というユーザーは存在しませんでした... もう一度教えてください:`; + } else { + this.temporaryUser = user; + return `パスワードを教えてください:`; + } + } else { + // Compare password + const same = bcrypt.compareSync(query, this.temporaryUser.password); + + if (same) { + this.core.setUser(this.temporaryUser); + return `${this.temporaryUser.name}さん、おかえりなさい!`; + } else { + return `パスワードが違います... もう一度教えてください:`; + } + } + } +} diff --git a/src/api/bot/interfaces/line.ts b/src/api/bot/interfaces/line.ts new file mode 100644 index 0000000000..4bee844c12 --- /dev/null +++ b/src/api/bot/interfaces/line.ts @@ -0,0 +1,37 @@ +import * as EventEmitter from 'events'; +import * as express from 'express'; +import * as crypto from 'crypto'; +//import User from '../../models/user'; +import config from '../../../conf'; +/*import BotCore from '../core'; + +const sessions: { + userId: string; + session: BotCore; +}[] = []; +*/ +module.exports = async (app: express.Application) => { + if (config.line_bot == null) return; + + const handler = new EventEmitter(); + + app.post('/hooks/line', (req, res, next) => { + // req.headers['X-Line-Signature'] は常に string ですが、型定義の都合上 + // string | string[] になっているので string を明示しています + const sig1 = req.headers['X-Line-Signature'] as string; + + const hash = crypto.createHmac('sha256', config.line_bot.channel_secret) + .update(JSON.stringify(req.body)); + + const sig2 = hash.digest('base64'); + + // シグネチャ比較 + if (sig1 === sig2) { + console.log(req.body); + handler.emit(req.body.type); + res.sendStatus(200); + } else { + res.sendStatus(400); + } + }); +}; diff --git a/src/api/endpoints/i/appdata/set.ts b/src/api/endpoints/i/appdata/set.ts index 24f192de6b..9c3dbe185b 100644 --- a/src/api/endpoints/i/appdata/set.ts +++ b/src/api/endpoints/i/appdata/set.ts @@ -21,7 +21,7 @@ module.exports = (params, user, app, isSecure) => new Promise(async (res, rej) = const [data, dataError] = $(params.data).optional.object() .pipe(obj => { const hasInvalidData = Object.entries(obj).some(([k, v]) => - $(k).string().match(/^[a-z_]+$/).isNg() && $(v).string().isNg()); + $(k).string().match(/^[a-z_]+$/).nok() && $(v).string().nok()); return !hasInvalidData; }).$; if (dataError) return rej('invalid data param'); diff --git a/src/api/models/user.ts b/src/api/models/user.ts index 1591b339bc..4f8086d42b 100644 --- a/src/api/models/user.ts +++ b/src/api/models/user.ts @@ -57,6 +57,9 @@ export type IUser = { user_id: string; screen_name: string; }; + line: { + user_id: string; + }; description: string; profile: { location: string; diff --git a/src/api/serializers/user.ts b/src/api/serializers/user.ts index 23a176096a..3deff2d003 100644 --- a/src/api/serializers/user.ts +++ b/src/api/serializers/user.ts @@ -79,6 +79,7 @@ export default ( delete _user.twitter.access_token; delete _user.twitter.access_token_secret; } + delete _user.line; // Visible via only the official client if (!opts.includeSecrets) { diff --git a/src/api/server.ts b/src/api/server.ts index c98167eb3e..fdff0c7546 100644 --- a/src/api/server.ts +++ b/src/api/server.ts @@ -54,4 +54,6 @@ app.use((req, res, next) => { require('./service/github')(app); require('./service/twitter')(app); +require('./bot/interfaces/line')(app); + module.exports = app; diff --git a/src/common/get-post-summary.js b/src/common/get-post-summary.js new file mode 100644 index 0000000000..f7a481a164 --- /dev/null +++ b/src/common/get-post-summary.js @@ -0,0 +1,39 @@ +/** + * 投稿を表す文字列を取得します。 + * @param {*} post 投稿 + */ +const summarize = post => { + let summary = post.text ? post.text : ''; + + // メディアが添付されているとき + if (post.media) { + summary += ` (${post.media.length}つのメディア)`; + } + + // 投票が添付されているとき + if (post.poll) { + summary += ' (投票)'; + } + + // 返信のとき + if (post.reply_to_id) { + if (post.reply_to) { + summary += ` RE: ${summarize(post.reply_to)}`; + } else { + summary += ' RE: ...'; + } + } + + // Repostのとき + if (post.repost_id) { + if (post.repost) { + summary += ` RP: ${summarize(post.repost)}`; + } else { + summary += ' RP: ...'; + } + } + + return summary.trim(); +}; + +export default summarize; diff --git a/src/config.ts b/src/config.ts index f8facdee2e..0ea332f67d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -68,6 +68,9 @@ type Source = { hook_secret: string; username: string; }; + line_bot?: { + channel_secret: string; + }; analysis?: { mecab_command?: string; }; diff --git a/src/web/app/common/scripts/get-post-summary.js b/src/web/app/common/scripts/get-post-summary.js deleted file mode 100644 index 83eda8f6b4..0000000000 --- a/src/web/app/common/scripts/get-post-summary.js +++ /dev/null @@ -1,35 +0,0 @@ -const summarize = post => { - let summary = post.text ? post.text : ''; - - // メディアが添付されているとき - if (post.media) { - summary += ` (${post.media.length}つのメディア)`; - } - - // 投票が添付されているとき - if (post.poll) { - summary += ' (投票)'; - } - - // 返信のとき - if (post.reply_to_id) { - if (post.reply_to) { - summary += ` RE: ${summarize(post.reply_to)}`; - } else { - summary += ' RE: ...'; - } - } - - // Repostのとき - if (post.repost_id) { - if (post.repost) { - summary += ` RP: ${summarize(post.repost)}`; - } else { - summary += ' RP: ...'; - } - } - - return summary.trim(); -}; - -export default summarize; diff --git a/src/web/app/desktop/script.js b/src/web/app/desktop/script.js index 2e81147943..e3dc8b7d96 100644 --- a/src/web/app/desktop/script.js +++ b/src/web/app/desktop/script.js @@ -11,7 +11,7 @@ import * as riot from 'riot'; import init from '../init'; import route from './router'; import fuckAdBlock from './scripts/fuck-ad-block'; -import getPostSummary from '../common/scripts/get-post-summary'; +import getPostSummary from '../../../common/get-post-summary'; /** * init diff --git a/src/web/app/desktop/tags/notifications.tag b/src/web/app/desktop/tags/notifications.tag index 21e4fe7fa5..4747d1c0f4 100644 --- a/src/web/app/desktop/tags/notifications.tag +++ b/src/web/app/desktop/tags/notifications.tag @@ -207,7 +207,7 @@ diff --git a/src/web/app/mobile/tags/notification.tag b/src/web/app/mobile/tags/notification.tag index 3663709525..416493ee23 100644 --- a/src/web/app/mobile/tags/notification.tag +++ b/src/web/app/mobile/tags/notification.tag @@ -163,7 +163,7 @@ diff --git a/src/web/app/mobile/tags/notifications.tag b/src/web/app/mobile/tags/notifications.tag index 2f314769db..9985b3351c 100644 --- a/src/web/app/mobile/tags/notifications.tag +++ b/src/web/app/mobile/tags/notifications.tag @@ -78,7 +78,7 @@ diff --git a/src/web/app/mobile/tags/ui-header.tag b/src/web/app/mobile/tags/ui-header.tag deleted file mode 100644 index 10b44b2153..0000000000 --- a/src/web/app/mobile/tags/ui-header.tag +++ /dev/null @@ -1,156 +0,0 @@ - - -
-
-
- - -

Misskey

- -
-
- - -
diff --git a/src/web/app/mobile/tags/ui-nav.tag b/src/web/app/mobile/tags/ui-nav.tag deleted file mode 100644 index 34235ba4f1..0000000000 --- a/src/web/app/mobile/tags/ui-nav.tag +++ /dev/null @@ -1,170 +0,0 @@ - -
- - - -
diff --git a/src/web/app/mobile/tags/ui.tag b/src/web/app/mobile/tags/ui.tag index 9d9cd4d74a..fb8cbcdbd2 100644 --- a/src/web/app/mobile/tags/ui.tag +++ b/src/web/app/mobile/tags/ui.tag @@ -30,9 +30,377 @@ }; this.onStreamNotification = notification => { + // TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない + this.stream.send({ + type: 'read_notification', + id: notification.id + }); + riot.mount(document.body.appendChild(document.createElement('mk-notify')), { notification: notification }); }; + + + +
+
+
+ + +

Misskey

+ +
+
+ + +
+ + +
+ + + +
-- cgit v1.2.3-freya