diff --git a/src/web/app/auth/script.js b/src/web/app/auth/script.js
index 9743415b1..9ada80ce6 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 000000000..e626c35f5
--- /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 d1230f8f0..000000000
--- 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 473797334..179cfa332 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 407f4e84c..575f545b2 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 1c269a57d..0da0a985c 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');