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 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/api/bot/core.ts (limited to 'src/api/bot/core.ts') 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 `パスワードが違います... もう一度教えてください:`; + } + } + } +} -- cgit v1.2.3-freya From fffea98462b7ba3250118b4bdf4e5678cf6e4ba7 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 7 Oct 2017 04:30:57 +0900 Subject: :v: --- src/api/bot/core.ts | 4 +-- src/api/bot/interfaces/line.ts | 65 +++++++++++++++++++++++++++++++++++------- src/api/server.ts | 7 ++++- src/config.ts | 1 + tslint.json | 1 + 5 files changed, 64 insertions(+), 14 deletions(-) (limited to 'src/api/bot/core.ts') diff --git a/src/api/bot/core.ts b/src/api/bot/core.ts index 002ac1b06e..47989dbaa2 100644 --- a/src/api/bot/core.ts +++ b/src/api/bot/core.ts @@ -4,11 +4,11 @@ import * as bcrypt from 'bcryptjs'; import User, { IUser } from '../models/user'; export default class BotCore extends EventEmitter { - public user: IUser; + public user: IUser = null; private context: Context = null; - constructor(user: IUser) { + constructor(user?: IUser) { super(); this.user = user; diff --git a/src/api/bot/interfaces/line.ts b/src/api/bot/interfaces/line.ts index 4bee844c12..8c7d6acfd5 100644 --- a/src/api/bot/interfaces/line.ts +++ b/src/api/bot/interfaces/line.ts @@ -1,34 +1,77 @@ import * as EventEmitter from 'events'; import * as express from 'express'; +import * as request from 'request'; import * as crypto from 'crypto'; //import User from '../../models/user'; import config from '../../../conf'; -/*import BotCore from '../core'; +import BotCore from '../core'; -const sessions: { - userId: string; +const sessions: Array<{ + sourceId: string; session: BotCore; -}[] = []; -*/ +}> = []; + module.exports = async (app: express.Application) => { if (config.line_bot == null) return; const handler = new EventEmitter(); + handler.on('message', async (ev) => { + // テキスト以外(スタンプなど)は無視 + if (ev.message.type !== 'text') return; + + const sourceId = ev.source.userId; + let session = sessions.find(s => { + return s.sourceId === sourceId; + }); + + if (!session) { + session = { + sourceId: sourceId, + session: new BotCore() + }; + + sessions.push(session); + } + + const res = await session.session.q(ev.message.text); + + request({ + url: 'https://api.line.me/v2/bot/message/reply', + headers: { + 'Authorization': `Bearer ${config.line_bot.channel_access_token}` + }, + json: { + replyToken: ev.replyToken, + messages: [{ + type: 'text', + text: res + }] + } + }, (err, res, body) => { + if (err) { + console.error(err); + return; + } + }); + }); + app.post('/hooks/line', (req, res, next) => { - // req.headers['X-Line-Signature'] は常に string ですが、型定義の都合上 + // req.headers['x-line-signature'] は常に string ですが、型定義の都合上 // string | string[] になっているので string を明示しています - const sig1 = req.headers['X-Line-Signature'] as 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 hash = crypto.createHmac('SHA256', config.line_bot.channel_secret) + .update((req as any).rawBody); const sig2 = hash.digest('base64'); // シグネチャ比較 if (sig1 === sig2) { - console.log(req.body); - handler.emit(req.body.type); + req.body.events.forEach(ev => { + handler.emit(ev.type, ev); + }); + res.sendStatus(200); } else { res.sendStatus(400); diff --git a/src/api/server.ts b/src/api/server.ts index fdff0c7546..3de32d9eab 100644 --- a/src/api/server.ts +++ b/src/api/server.ts @@ -19,7 +19,12 @@ app.disable('x-powered-by'); app.set('etag', false); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json({ - type: ['application/json', 'text/plain'] + type: ['application/json', 'text/plain'], + verify: (req, res, buf, encoding) => { + if (buf && buf.length) { + (req as any).rawBody = buf.toString(encoding || 'utf8'); + } + } })); app.use(cors({ origin: true diff --git a/src/config.ts b/src/config.ts index 0ea332f67d..46a93f5fef 100644 --- a/src/config.ts +++ b/src/config.ts @@ -70,6 +70,7 @@ type Source = { }; line_bot?: { channel_secret: string; + channel_access_token: string; }; analysis?: { mecab_command?: string; diff --git a/tslint.json b/tslint.json index 33704ca43b..1c44579512 100644 --- a/tslint.json +++ b/tslint.json @@ -16,6 +16,7 @@ "ordered-imports": [false], "arrow-parens": false, "object-literal-shorthand": false, + "object-literal-key-quotes": false, "triple-equals": [false], "no-shadowed-variable": false, "no-string-literal": false, -- cgit v1.2.3-freya From 0f2b503f2f545ce11fcca8c2c17a1084fd91df5e Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 7 Oct 2017 05:50:01 +0900 Subject: :v: --- src/api/bot/core.ts | 52 ++++++++++++++++++++++++++++++++++++++++-- src/api/bot/interfaces/line.ts | 38 +++++++++++++++--------------- 2 files changed, 70 insertions(+), 20 deletions(-) (limited to 'src/api/bot/core.ts') diff --git a/src/api/bot/core.ts b/src/api/bot/core.ts index 47989dbaa2..1f624c5f0a 100644 --- a/src/api/bot/core.ts +++ b/src/api/bot/core.ts @@ -14,6 +14,31 @@ export default class BotCore extends EventEmitter { this.user = user; } + private setContect(context: Context) { + this.context = context; + this.emit('updated'); + + if (context) { + context.on('updated', () => { + this.emit('updated'); + }); + } + } + + public export() { + return { + user: this.user, + context: this.context ? this.context.export() : null + }; + } + + public static import(data) { + const core = new BotCore(); + core.user = data.user; + core.setContect(data.context ? Context.import(core, data.context) : null); + return core; + } + public async q(query: string): Promise { if (this.context != null) { return await this.context.q(query); @@ -22,9 +47,11 @@ export default class BotCore extends EventEmitter { switch (query) { case 'ping': return 'PONG'; + case 'me': + return this.user ? `${this.user.name}としてサインインしています` : 'サインインしていません'; case 'ログイン': case 'サインイン': - this.context = new SigninContext(this); + this.setContect(new SigninContext(this)); return await this.context.greet(); default: return '?'; @@ -34,18 +61,26 @@ export default class BotCore extends EventEmitter { public setUser(user: IUser) { this.user = user; this.emit('set-user', user); + this.emit('updated'); } } -abstract class Context { +abstract class Context extends EventEmitter { protected core: BotCore; public abstract async greet(): Promise; public abstract async q(query: string): Promise; + public abstract export(): any; constructor(core: BotCore) { + super(); this.core = core; } + + public static import(core: BotCore, data: any) { + if (data.type == 'signin') return SigninContext.import(core, data.content); + return null; + } } class SigninContext extends Context { @@ -71,6 +106,7 @@ class SigninContext extends Context { return `${query}というユーザーは存在しませんでした... もう一度教えてください:`; } else { this.temporaryUser = user; + this.emit('updated'); return `パスワードを教えてください:`; } } else { @@ -85,4 +121,16 @@ class SigninContext extends Context { } } } + + public export() { + return { + temporaryUser: this.temporaryUser + }; + } + + public static import(core: BotCore, data: any) { + const context = new SigninContext(core); + context.temporaryUser = data.temporaryUser; + return context; + } } diff --git a/src/api/bot/interfaces/line.ts b/src/api/bot/interfaces/line.ts index 9e1c813570..61aa728121 100644 --- a/src/api/bot/interfaces/line.ts +++ b/src/api/bot/interfaces/line.ts @@ -5,11 +5,10 @@ import * as crypto from 'crypto'; import User from '../../models/user'; import config from '../../../conf'; import BotCore from '../core'; +import _redis from '../../../db/redis'; +import prominence = require('prominence'); -const sessions: Array<{ - sourceId: string; - core: BotCore; -}> = []; +const redis = prominence(_redis); module.exports = async (app: express.Application) => { if (config.line_bot == null) return; @@ -21,22 +20,23 @@ module.exports = async (app: express.Application) => { if (ev.message.type !== 'text') return; const sourceId = ev.source.userId; - let session = sessions.find(s => s.sourceId === sourceId); + const sessionId = `line-bot-sessions:${sourceId}`; - if (!session) { + const _session = await redis.get(sessionId); + let session: BotCore; + + if (_session == null) { const user = await User.findOne({ line: { user_id: sourceId } }); - let core: BotCore; - if (user) { - core = new BotCore(user); + session = new BotCore(user); } else { - core = new BotCore(); - core.on('set-user', user => { + session = new BotCore(); + session.on('set-user', user => { User.update(user._id, { $set: { line: { @@ -47,16 +47,18 @@ module.exports = async (app: express.Application) => { }); } - session = { - sourceId: sourceId, - core: core - }; - - sessions.push(session); + redis.set(sessionId, JSON.stringify(session.export())); + } else { + session = BotCore.import(JSON.parse(_session)); } - const res = await session.core.q(ev.message.text); + session.on('updated', () => { + redis.set(sessionId, JSON.stringify(session.export())); + }); + + const res = await session.q(ev.message.text); + // 返信 request.post({ url: 'https://api.line.me/v2/bot/message/reply', headers: { -- cgit v1.2.3-freya From f5fe36825b0c83d8770e0f3cdf5c2d477eb2b995 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 7 Oct 2017 06:03:16 +0900 Subject: :v: --- src/api/bot/core.ts | 5 +++-- src/api/bot/interfaces/line.ts | 20 ++++++++------------ 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src/api/bot/core.ts') diff --git a/src/api/bot/core.ts b/src/api/bot/core.ts index 1f624c5f0a..4109519ca5 100644 --- a/src/api/bot/core.ts +++ b/src/api/bot/core.ts @@ -34,7 +34,7 @@ export default class BotCore extends EventEmitter { public static import(data) { const core = new BotCore(); - core.user = data.user; + core.user = data.user ? data.user : null; core.setContect(data.context ? Context.import(core, data.context) : null); return core; } @@ -84,7 +84,7 @@ abstract class Context extends EventEmitter { } class SigninContext extends Context { - private temporaryUser: IUser; + private temporaryUser: IUser = null; public async greet(): Promise { return 'まずユーザー名を教えてください:'; @@ -124,6 +124,7 @@ class SigninContext extends Context { public export() { return { + type: 'signin', temporaryUser: this.temporaryUser }; } diff --git a/src/api/bot/interfaces/line.ts b/src/api/bot/interfaces/line.ts index 61aa728121..52559eaeff 100644 --- a/src/api/bot/interfaces/line.ts +++ b/src/api/bot/interfaces/line.ts @@ -32,20 +32,16 @@ module.exports = async (app: express.Application) => { } }); - if (user) { - session = new BotCore(user); - } else { - session = new BotCore(); - session.on('set-user', user => { - User.update(user._id, { - $set: { - line: { - user_id: sourceId - } + session = new BotCore(user); + session.on('set-user', user => { + User.update(user._id, { + $set: { + line: { + user_id: sourceId } - }); + } }); - } + }); redis.set(sessionId, JSON.stringify(session.export())); } else { -- cgit v1.2.3-freya From 1d4f9378ca57dc9a19d4ff13e676669e01814612 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 7 Oct 2017 06:43:36 +0900 Subject: :v: --- src/api/bot/core.ts | 99 ++++++++++++++++++++++++++++++++++++++---- src/api/bot/interfaces/line.ts | 13 +++++- src/tsconfig.json | 1 + tsconfig.json | 1 + 4 files changed, 105 insertions(+), 9 deletions(-) (limited to 'src/api/bot/core.ts') diff --git a/src/api/bot/core.ts b/src/api/bot/core.ts index 4109519ca5..cf2bdef1dc 100644 --- a/src/api/bot/core.ts +++ b/src/api/bot/core.ts @@ -3,6 +3,8 @@ import * as bcrypt from 'bcryptjs'; import User, { IUser } from '../models/user'; +import getPostSummary from '../../common/get-post-summary.js'; + export default class BotCore extends EventEmitter { public user: IUser = null; @@ -14,7 +16,7 @@ export default class BotCore extends EventEmitter { this.user = user; } - private setContect(context: Context) { + public setContext(context: Context) { this.context = context; this.emit('updated'); @@ -35,7 +37,7 @@ export default class BotCore extends EventEmitter { public static import(data) { const core = new BotCore(); core.user = data.user ? data.user : null; - core.setContect(data.context ? Context.import(core, data.context) : null); + core.setContext(data.context ? Context.import(core, data.context) : null); return core; } @@ -47,22 +49,74 @@ export default class BotCore extends EventEmitter { switch (query) { case 'ping': return 'PONG'; + + case 'help': + case 'ヘルプ': + return 'コマンド一覧です:' + + 'help: これです\n' + + 'me: アカウント情報を見ます\n' + + 'login, signin: サインインします\n' + + 'logout, signout: サインアウトします\n' + + 'post: 投稿します\n' + + 'tl: タイムラインを見ます\n'; + case 'me': return this.user ? `${this.user.name}としてサインインしています` : 'サインインしていません'; + + case 'login': + case 'signin': case 'ログイン': case 'サインイン': - this.setContect(new SigninContext(this)); + this.setContext(new SigninContext(this)); return await this.context.greet(); - default: + + case 'logout': + case 'signout': + case 'ログアウト': + case 'サインアウト': + if (this.user == null) return '今はサインインしてないですよ!'; + this.signout(); + return 'ご利用ありがとうございました <3'; + + case 'post': + case '投稿': + if (this.user == null) return 'まずサインインしてください。'; + this.setContext(new PostContext(this)); + return await this.context.greet(); + + case 'tl': + case 'タイムライン': + return await this.getTl(); + + default: return '?'; } } - public setUser(user: IUser) { + public signin(user: IUser) { this.user = user; - this.emit('set-user', user); + this.emit('signin', user); this.emit('updated'); } + + public signout() { + const user = this.user; + this.user = null; + this.emit('signout', user); + this.emit('updated'); + } + + public async getTl() { + if (this.user == null) return 'まずサインインしてください。'; + + const tl = await require('../endpoints/posts/timeline')({}, this.user); + + const text = tl + .map(post => getPostSummary(post)) + .join('\n-----\n'); + + return text; + } } abstract class Context extends EventEmitter { @@ -78,6 +132,7 @@ abstract class Context extends EventEmitter { } public static import(core: BotCore, data: any) { + if (data.type == 'post') return PostContext.import(core, data.content); if (data.type == 'signin') return SigninContext.import(core, data.content); return null; } @@ -114,7 +169,8 @@ class SigninContext extends Context { const same = bcrypt.compareSync(query, this.temporaryUser.password); if (same) { - this.core.setUser(this.temporaryUser); + this.core.signin(this.temporaryUser); + this.core.setContext(null); return `${this.temporaryUser.name}さん、おかえりなさい!`; } else { return `パスワードが違います... もう一度教えてください:`; @@ -125,7 +181,9 @@ class SigninContext extends Context { public export() { return { type: 'signin', - temporaryUser: this.temporaryUser + content: { + temporaryUser: this.temporaryUser + } }; } @@ -135,3 +193,28 @@ class SigninContext extends Context { return context; } } + +class PostContext extends Context { + public async greet(): Promise { + return '内容:'; + } + + public async q(query: string): Promise { + await require('../endpoints/posts/create')({ + text: query + }, this.core.user); + this.core.setContext(null); + return '投稿しましたよ!'; + } + + public export() { + return { + type: 'post' + }; + } + + public static import(core: BotCore, data: any) { + const context = new PostContext(core); + return context; + } +} diff --git a/src/api/bot/interfaces/line.ts b/src/api/bot/interfaces/line.ts index 52559eaeff..437f29cb3c 100644 --- a/src/api/bot/interfaces/line.ts +++ b/src/api/bot/interfaces/line.ts @@ -33,7 +33,8 @@ module.exports = async (app: express.Application) => { }); session = new BotCore(user); - session.on('set-user', user => { + + session.on('signin', user => { User.update(user._id, { $set: { line: { @@ -43,6 +44,16 @@ module.exports = async (app: express.Application) => { }); }); + session.on('signout', user => { + User.update(user._id, { + $set: { + line: { + user_id: null + } + } + }); + }); + redis.set(sessionId, JSON.stringify(session.export())); } else { session = BotCore.import(JSON.parse(_session)); diff --git a/src/tsconfig.json b/src/tsconfig.json index ecff047a74..36600eed2b 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "allowJs": true, "noEmitOnError": false, "noImplicitAny": false, "noImplicitReturns": true, diff --git a/tsconfig.json b/tsconfig.json index 064a04e4d2..a38ff220b2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "allowJs": true, "noEmitOnError": false, "noImplicitAny": false, "noImplicitReturns": true, -- cgit v1.2.3-freya From fe98dd927de6906671dfd3aa9671080ab6a065c6 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 7 Oct 2017 06:58:50 +0900 Subject: :v: --- package.json | 3 +- src/api/bot/core.ts | 6 ++-- src/common/get-post-summary.js | 39 ------------------------ src/common/get-post-summary.ts | 39 ++++++++++++++++++++++++ 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 +- webpack/module/rules/index.ts | 4 ++- webpack/module/rules/typescript.ts | 8 +++++ 16 files changed, 66 insertions(+), 53 deletions(-) delete mode 100644 src/common/get-post-summary.js create mode 100644 src/common/get-post-summary.ts create mode 100644 webpack/module/rules/typescript.ts (limited to 'src/api/bot/core.ts') diff --git a/package.json b/package.json index 0336725bda..6a9e7e26f0 100644 --- a/package.json +++ b/package.json @@ -64,14 +64,15 @@ "@types/webpack": "3.0.13", "@types/webpack-stream": "3.2.7", "@types/websocket": "0.0.34", + "awesome-typescript-loader": "^3.2.3", "chai": "4.1.2", "chai-http": "3.0.0", "css-loader": "0.28.7", "event-stream": "3.3.4", "gulp": "3.9.1", "gulp-cssnano": "2.1.2", - "gulp-imagemin": "3.4.0", "gulp-htmlmin": "3.0.0", + "gulp-imagemin": "3.4.0", "gulp-mocha": "4.3.1", "gulp-pug": "3.3.0", "gulp-rename": "1.2.2", diff --git a/src/api/bot/core.ts b/src/api/bot/core.ts index cf2bdef1dc..57330e67eb 100644 --- a/src/api/bot/core.ts +++ b/src/api/bot/core.ts @@ -3,7 +3,7 @@ import * as bcrypt from 'bcryptjs'; import User, { IUser } from '../models/user'; -import getPostSummary from '../../common/get-post-summary.js'; +import getPostSummary from '../../common/get-post-summary'; export default class BotCore extends EventEmitter { public user: IUser = null; @@ -109,7 +109,9 @@ export default class BotCore extends EventEmitter { public async getTl() { if (this.user == null) return 'まずサインインしてください。'; - const tl = await require('../endpoints/posts/timeline')({}, this.user); + const tl = await require('../endpoints/posts/timeline')({ + limit: 5 + }, this.user); const text = tl .map(post => getPostSummary(post)) diff --git a/src/common/get-post-summary.js b/src/common/get-post-summary.js deleted file mode 100644 index f7a481a164..0000000000 --- a/src/common/get-post-summary.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 投稿を表す文字列を取得します。 - * @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/common/get-post-summary.ts b/src/common/get-post-summary.ts new file mode 100644 index 0000000000..f628a32b41 --- /dev/null +++ b/src/common/get-post-summary.ts @@ -0,0 +1,39 @@ +/** + * 投稿を表す文字列を取得します。 + * @param {*} post 投稿 + */ +const summarize = (post: any): string => { + 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 e3dc8b7d96..46a7fce700 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/get-post-summary'; +import getPostSummary from '../../../common/get-post-summary.ts'; /** * init diff --git a/src/web/app/desktop/tags/notifications.tag b/src/web/app/desktop/tags/notifications.tag index 4747d1c0f4..1046358ce9 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 416493ee23..53222b9dbe 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 9985b3351c..7370aa84d3 100644 --- a/src/web/app/mobile/tags/notifications.tag +++ b/src/web/app/mobile/tags/notifications.tag @@ -78,7 +78,7 @@