diff --git a/src/web/app/auth/script.js b/src/web/app/auth/script.js index 9743415b12..9ada80ce68 100644 --- a/src/web/app/auth/script.js +++ b/src/web/app/auth/script.js @@ -5,7 +5,7 @@ const riot = require('riot'); document.title = 'Misskey | アプリの連携'; require('./tags.ls'); -const boot = require('../boot.ls'); +const boot = require('../boot.js'); /** * Boot diff --git a/src/web/app/boot.js b/src/web/app/boot.js new file mode 100644 index 0000000000..e626c35f5c --- /dev/null +++ b/src/web/app/boot.js @@ -0,0 +1,169 @@ +/* +MISSKEY BOOT LOADER + +Misskeyを起動します。 +1. 初期化 +2. ユーザー取得(ログインしていれば) +3. アプリケーションをマウント +*/ + +// LOAD DEPENDENCIES + +const riot = require('riot'); +require('velocity'); +const log = require('./common/scripts/log.ls'); +const api = require('./common/scripts/api.ls'); +const signout = require('./common/scripts/signout.ls'); +const generateDefaultUserdata = require('./common/scripts/generate-default-userdata.ls'); +const mixins = require('./common/mixins.ls'); +const checkForUpdate = require('./common/scripts/check-for-update.ls'); +require('./common/tags.ls'); + +// MISSKEY ENTORY POINT + +document.domain = CONFIG.host; + +// ↓ iOS待ちPolyfill (SEE: http://caniuse.com/#feat=fetch) +require('fetch'); + +// ↓ NodeList、HTMLCollectionで forEach を使えるようにする +if (NodeList.prototype.forEach === undefined) { + NodeList.prototype.forEach = Array.prototype.forEach; +} +if (HTMLCollection.prototype.forEach === undefined) { + HTMLCollection.prototype.forEach = Array.prototype.forEach; +} + +// ↓ iOSでプライベートモードだとlocalStorageが使えないので既存のメソッドを上書きする +try { + localStorage.setItem('kyoppie', 'yuppie'); +} catch (e) { + Storage.prototype.setItem = () => { }; // noop +} + +// MAIN PROCESS + +log("Misskey (aoi) v:" + VERSION); + +// Check for Update +checkForUpdate(); + +// Get token from cookie +const i = (document.cookie.match(/i=(\w+)/) || [null, null])[1]; + +if (i != null) { + log("ME: " + i); +} + +// ユーザーをフェッチしてコールバックする +module.exports = callback => { + // Get cached account data + let cachedMe = JSON.parse(localStorage.getItem('me')); + + if (cachedMe != null && cachedMe.data != null && cachedMe.data.cache) { + fetched(cachedMe); + + // 後から新鮮なデータをフェッチ + fetchme(i, true, freshData => { + Object.assign(cachedMe, freshData); + cachedMe.trigger('updated'); + }); + } else { + // キャッシュ無効なのにキャッシュが残ってたら掃除 + if (cachedMe != null) { + localStorage.removeItem('me'); + } + fetchme(i, false, fetched); + } + + function fetched(me) { + if (me != null) { + riot.observable(me); + if (me.data.cache) { + localStorage.setItem('me', JSON.stringify(me)); + me.on('updated', () => { + // キャッシュ更新 + localStorage.setItem('me', JSON.stringify(me)); + }); + } + log("Fetched! Hello " + me.username + "."); + } + mixins(me); + const init = document.getElementById('init'); + init.parentNode.removeChild(init); + const app = document.createElement('div'); + app.setAttribute('id', 'app'); + document.body.appendChild(app); + try { + callback(me); + } catch (e) { + panic(e); + } + } +}; + +// ユーザーをフェッチしてコールバックする +function fetchme(token, silent, cb) { + let me = null; + + // Return when not signed in + if (token == null) { + done(); + } + + // Fetch user + fetch(CONFIG.api.url + "/i", { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' + }, + body: "i=" + token + }).then(res => { + // When failed to authenticate user + if (res.status !== 200) { + signout(); + } + res.json().then(i => { + me = i; + me.token = token; + + // initialize it if user data is empty + if (me.data != null) { + done(); + } else { + init(); + } + }); + }).catch(() => { + if (!silent) { + const info = document.body.appendChild(document.createElement('mk-core-error')); + riot.mount(info, { + retry: () => { + fetchme(token, false, cb); + } + }); + } + }); + + function done() { + if (cb != null) { + cb(me); + } + } + + function init() { + var data, this$ = this; + data = generateDefaultUserdata(); + api(token, 'i/appdata/set', { + data: JSON.stringify(data) + }).then(() => { + me.data = data; + done(); + }); + } +} + +function panic(e) { + console.error(e); + document.body.innerHTML = '

致命的な問題が発生しました。

'; +} diff --git a/src/web/app/boot.ls b/src/web/app/boot.ls deleted file mode 100644 index d1230f8f0b..0000000000 --- a/src/web/app/boot.ls +++ /dev/null @@ -1,154 +0,0 @@ -#================================ -# MISSKEY BOOT LOADER -# -# Misskeyを起動します。 -# 1. 初期化 -# 2. ユーザー取得(ログインしていれば) -# 3. アプリケーションをマウント -#================================ - -# LOAD DEPENDENCIES -#-------------------------------- - -riot = require \riot -require \velocity -log = require './common/scripts/log.ls' -api = require './common/scripts/api.ls' -signout = require './common/scripts/signout.ls' -generate-default-userdata = require './common/scripts/generate-default-userdata.ls' -mixins = require './common/mixins.ls' -check-for-update = require './common/scripts/check-for-update.ls' -require './common/tags.ls' - -# MISSKEY ENTORY POINT -#-------------------------------- - -# for subdomains -document.domain = CONFIG.host - -# ↓ iOS待ちPolyfill (SEE: http://caniuse.com/#feat=fetch) -require \fetch - -# ↓ NodeList、HTMLCollectionで forEach を使えるようにする -if NodeList.prototype.for-each == undefined - NodeList.prototype.for-each = Array.prototype.for-each -if HTMLCollection.prototype.for-each == undefined - HTMLCollection.prototype.for-each = Array.prototype.for-each - -# ↓ iOSでプライベートモードだとlocalStorageが使えないので既存のメソッドを上書きする -try - local-storage.set-item \kyoppie \yuppie -catch e - Storage.prototype.set-item = ~> # noop - -# MAIN PROCESS -#-------------------------------- - -log "Misskey (aoi) v:#{VERSION}" - -# Check for Update -check-for-update! - -# Get token from cookie -i = ((document.cookie.match /i=(\w+)/) || [null null]).1 - -if i? then log "ME: #{i}" - -# ユーザーをフェッチしてコールバックする -module.exports = (callback) ~> - # Get cached account data - cached-me = JSON.parse local-storage.get-item \me - - if cached-me?.data?.cache - fetched cached-me - - # 後から新鮮なデータをフェッチ - fetchme i, true, (fresh-data) ~> - Object.assign cached-me, fresh-data - cached-me.trigger \updated - else - # キャッシュ無効なのにキャッシュが残ってたら掃除 - if cached-me? - local-storage.remove-item \me - - fetchme i, false, fetched - - function fetched me - - if me? - riot.observable me - - if me.data.cache - local-storage.set-item \me JSON.stringify me - - me.on \updated ~> - # キャッシュ更新 - local-storage.set-item \me JSON.stringify me - - log "Fetched! Hello #{me.username}." - - # activate mixins - mixins me - - # destroy loading screen - init = document.get-element-by-id \init - init.parent-node.remove-child init - - # set main element - document.create-element \div - ..set-attribute \id \app - .. |> document.body.append-child - - # Call main proccess - try - callback me - catch error - panic error - -# ユーザーをフェッチしてコールバックする -function fetchme token, silent, cb - me = null - - # Return when not signed in - if not token? then return done! - - # Fetch user - fetch "#{CONFIG.api.url}/i" do - method: \POST - headers: - 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' - body: "i=#token" - .then (res) ~> - # When failed to authenticate user - if res.status != 200 then signout! - - i <~ res.json!.then - me := i - me.token = token - - # initialize it if user data is empty - if me.data? then done! else init! - .catch ~> - if not silent - info = document.create-element \mk-core-error - |> document.body.append-child - riot.mount info, do - retry: ~> fetchme token, false, cb - else - # noop - - function done - if cb? then cb me - - function init - data = generate-default-userdata! - - api token, \i/appdata/set do - data: JSON.stringify data - .then ~> - me.data = data - done! - -function panic e - console.error e - document.body.innerHTML = '

致命的な問題が発生しました。

' diff --git a/src/web/app/desktop/script.js b/src/web/app/desktop/script.js index 473797334f..179cfa332a 100644 --- a/src/web/app/desktop/script.js +++ b/src/web/app/desktop/script.js @@ -5,7 +5,7 @@ require('chart.js'); require('./tags.ls'); const riot = require('riot'); -const boot = require('../boot.ls'); +const boot = require('../boot.js'); const mixins = require('./mixins.ls'); const route = require('./router.ls'); const fuckAdBlock = require('./scripts/fuck-ad-block.ls'); diff --git a/src/web/app/dev/script.js b/src/web/app/dev/script.js index 407f4e84c0..575f545b2c 100644 --- a/src/web/app/dev/script.js +++ b/src/web/app/dev/script.js @@ -3,7 +3,7 @@ */ require('./tags.ls'); -const boot = require('../boot.ls'); +const boot = require('../boot.js'); const route = require('./router.ls'); /** diff --git a/src/web/app/mobile/script.js b/src/web/app/mobile/script.js index 1c269a57d9..0da0a985c8 100644 --- a/src/web/app/mobile/script.js +++ b/src/web/app/mobile/script.js @@ -4,7 +4,7 @@ require('./tags.ls'); require('./scripts/sp-slidemenu.js'); -const boot = require('../boot.ls'); +const boot = require('../boot.js'); const mixins = require('./mixins.ls'); const route = require('./router.ls');