なんかもうめっちゃ変えた

Closes #940
This commit is contained in:
syuilo 2017-11-23 05:43:00 +09:00
parent 1809800980
commit 3f8ebac466
46 changed files with 244 additions and 225 deletions

View file

@ -22,5 +22,5 @@ elasticsearch:
port: 9200
pass: ''
recaptcha:
siteKey: hima
secretKey: saku
site_key: hima
secret_key: saku

View file

@ -22,5 +22,5 @@ elasticsearch:
port: 9200
pass: ''
recaptcha:
siteKey: hima
secretKey: saku
site_key: hima
secret_key: saku

55
docs/config.md Normal file
View file

@ -0,0 +1,55 @@
``` yaml
# サーバーのメンテナ情報
maintainer:
# メンテナの名前
name:
# メンテナの連絡先(URLかmailto形式のURL)
url:
# プライマリURL
url:
# セカンダリURL
secondary_url:
# 待受ポート
port:
# TLSの設定
https:
# TLSを有効にするか否か
enable: false
key: null
cert: null
ca: null
# MongoDBの設定
mongodb:
host: localhost
port: 27017
db: misskey
user:
pass:
# Redisの設定
redis:
host: localhost
port: 6379
pass:
# reCAPTCHAの設定
recaptcha:
site_key:
secret_key:
# ServiceWrokerの設定
sw:
# VAPIDの公開鍵
public_key:
# VAPIDの秘密鍵
private_key:
```

View file

@ -36,6 +36,15 @@ Note that Misskey uses following subdomains:
Misskey requires reCAPTCHA tokens.
Please visit https://www.google.com/recaptcha/intro/ and generate keys.
*(optional)* Generating VAPID keys
----------------------------------------------------------------
If you want to enable ServiceWroker, you need to generate VAPID keys:
``` shell
npm install web-push -g
web-push generate-vapid-keys
```
*3.* Install dependencies
----------------------------------------------------------------
Please install and setup these softwares:
@ -51,24 +60,6 @@ Please install and setup these softwares:
*4.* Install Misskey
----------------------------------------------------------------
There is **two ways** to install Misskey:
### WAY 1) Using built code (recommended)
We have the official release of Misskey.
The built code is automatically pushed to https://github.com/syuilo/misskey/tree/release after the CI test succeeds.
1. `git clone -b release git://github.com/syuilo/misskey.git`
2. `cd misskey`
3. `npm install`
#### Update
1. `git fetch`
2. `git reset --hard origin/release`
3. `npm install`
### WAY 2) Using source code
If you want to build Misskey manually, you can do it via the
`build` command after download the source code of Misskey and install dependencies:
1. `git clone -b master git://github.com/syuilo/misskey.git`
2. `cd misskey`

View file

@ -37,6 +37,15 @@ Misskeyは以下のサブドメインを使います:
MisskeyはreCAPTCHAトークンを必要とします。
https://www.google.com/recaptcha/intro/ にアクセスしてトークンを生成してください。
*(オプション)* VAPIDキーペアの生成
----------------------------------------------------------------
ServiceWorkerを有効にする場合、VAPIDキーペアを生成する必要があります:
``` shell
npm install web-push -g
web-push generate-vapid-keys
```
*3.* 依存関係をインストールする
----------------------------------------------------------------
これらのソフトウェアをインストール・設定してください:
@ -52,26 +61,6 @@ https://www.google.com/recaptcha/intro/ にアクセスしてトークンを生
*4.* Misskeyのインストール
----------------------------------------------------------------
Misskeyをインストールするには**2つの方法**があります:
### 方法 1) ビルドされたコードを利用する (推奨)
Misskeyには公式のリリースがあります。
ビルドされたコードはCIテストに合格した後、自動で https://github.com/syuilo/misskey/tree/release にpushされています。
1. `git clone -b release git://github.com/syuilo/misskey.git`
2. `cd misskey`
3. `npm install`
#### アップデートするには:
1. `git fetch`
2. `git reset --hard origin/release`
3. `npm install`
### 方法 2) ソースコードを利用する
> 注: この方法では正しくビルド・動作できることは保証されません。
Misskeyを手動でビルドしたい場合は、Misskeyのソースコードと依存関係をインストールした後、
`build`コマンドを用いることができます:
1. `git clone -b master git://github.com/syuilo/misskey.git`
2. `cd misskey`

View file

@ -4,7 +4,11 @@ import Subscription from '../models/sw-subscription';
import config from '../../conf';
if (config.sw) {
push.setGCMAPIKey(config.sw.gcm_api_key);
// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
push.setVapidDetails(
config.maintainer.url,
config.sw.public_key,
config.sw.private_key);
}
export default async function(userId: mongo.ObjectID | string, type, body?) {

View file

@ -9,7 +9,7 @@ import generateUserToken from '../common/generate-native-user-token';
import config from '../../conf';
recaptcha.init({
secret_key: config.recaptcha.secretKey
secret_key: config.recaptcha.secret_key
});
const home = {

View file

@ -3,7 +3,6 @@
*/
import * as fs from 'fs';
import * as URL from 'url';
import * as yaml from 'js-yaml';
import isUrl = require('is-url');
@ -23,7 +22,19 @@ export const path = process.env.NODE_ENV == 'test'
*
*/
type Source = {
maintainer: string;
/**
*
*/
maintainer: {
/**
*
*/
name: string;
/**
* (URLかmailto形式のURL)
*/
url: string;
};
url: string;
secondary_url: string;
port: number;
@ -52,8 +63,8 @@ type Source = {
pass: string;
};
recaptcha: {
siteKey: string;
secretKey: string;
site_key: string;
secret_key: string;
};
accesslog?: string;
accesses?: {
@ -80,8 +91,8 @@ type Source = {
* Service Worker
*/
sw?: {
gcm_sender_id: string;
gcm_api_key: string;
public_key: string;
private_key: string;
};
};
@ -114,14 +125,6 @@ export default function load() {
if (!isUrl(config.url)) urlError(config.url);
if (!isUrl(config.secondary_url)) urlError(config.secondary_url);
const url = URL.parse(config.url);
const head = url.host.split('.')[0];
if (head != 'misskey' && head != 'localhost') {
console.error(`プライマリドメインは、必ず「misskey」ドメインで始まっていなければなりません(現在の設定では「${head}」で始まっています)。例えば「https://misskey.xyz」「http://misskey.my.app.example.com」などが正しいプライマリURLです。`);
process.exit();
}
config.url = normalizeUrl(config.url);
config.secondary_url = normalizeUrl(config.secondary_url);

View file

@ -26,11 +26,11 @@
<hr>
<mk-channel-form if={ SIGNIN } channel={ channel } ref="form"/>
<div if={ !SIGNIN }>
<p>参加するには<a href={ CONFIG.url }>ログインまたは新規登録</a>してください</p>
<p>参加するには<a href={ _URL_ }>ログインまたは新規登録</a>してください</p>
</div>
<hr>
<footer>
<small><a href={ CONFIG.url }>Misskey</a> ver { version } (葵 aoi)</small>
<small><a href={ _URL_ }>Misskey</a> ver { _VERSION_ } (葵 aoi)</small>
</footer>
</main>
<style>
@ -66,7 +66,6 @@
this.channel = null;
this.posts = null;
this.connection = new ChannelStream(this.id);
this.version = VERSION;
this.unreadCount = 0;
this.on('mount', () => {
@ -166,7 +165,7 @@
<mk-channel-post>
<header>
<a class="index" onclick={ reply }>{ post.index }:</a>
<a class="name" href={ CONFIG.url + '/' + post.user.username }><b>{ post.user.name }</b></a>
<a class="name" href={ _URL_ + '/' + post.user.username }><b>{ post.user.name }</b></a>
<mk-time time={ post.created_at }/>
<mk-time time={ post.created_at } mode="detail"/>
<span>ID:<i>{ post.user.username }</i></span>
@ -284,8 +283,6 @@
</style>
<script>
import CONFIG from '../../common/scripts/config';
this.mixin('api');
this.channel = this.opts.channel;
@ -357,7 +354,7 @@
});
};
window.open(CONFIG.url + '/selectdrive?multiple=true',
window.open(_URL_ + '/selectdrive?multiple=true',
'drive_window',
'height=500,width=800');
};
@ -390,7 +387,7 @@
</mk-twitter-button>
<mk-line-button>
<div class="line-it-button" data-lang="ja" data-type="share-a" data-url={ CONFIG.chUrl } style="display: none;"></div>
<div class="line-it-button" data-lang="ja" data-type="share-a" data-url={ _CH_URL_ } style="display: none;"></div>
<script>
this.on('mount', () => {
const head = document.getElementsByTagName('head')[0];

View file

@ -1,10 +1,10 @@
<mk-header>
<div>
<a href={ CONFIG.chUrl }>Index</a> | <a href={ CONFIG.url }>Misskey</a>
<a href={ _CH_URL_ }>Index</a> | <a href={ _URL_ }>Misskey</a>
</div>
<div>
<a if={ !SIGNIN } href={ CONFIG.url }>ログイン(新規登録)</a>
<a if={ SIGNIN } href={ CONFIG.url + '/' + I.username }>{ I.username }</a>
<a if={ !SIGNIN } href={ _URL_ }>ログイン(新規登録)</a>
<a if={ SIGNIN } href={ _URL_ + '/' + I.username }>{ I.username }</a>
</div>
<style>
:scope

View file

@ -3,11 +3,12 @@ import * as riot from 'riot';
import signout from './scripts/signout';
import Progress from './scripts/loading';
import HomeStreamManager from './scripts/streaming/home-stream-manager';
import CONFIG from './scripts/config';
import api from './scripts/api';
declare var VERSION: string;
declare var LANG: string;
declare const _VERSION_: string;
declare const _LANG_: string;
declare const _API_URL_: string;
declare const _SW_PUBLICKEY_: string;
/**
* Misskey Operating System
@ -113,7 +114,7 @@ export default class MiOS extends EventEmitter {
}
// Fetch user
fetch(`${CONFIG.apiUrl}/i`, {
fetch(`${_API_URL_}/i`, {
method: 'POST',
body: JSON.stringify({
i: token
@ -229,10 +230,15 @@ export default class MiOS extends EventEmitter {
this.swRegistration = registration;
// Options of pushManager.subscribe
// SEE: https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe#Parameters
const opts = {
// A boolean indicating that the returned push subscription
// will only be used for messages whose effect is made visible to the user.
userVisibleOnly: true
userVisibleOnly: true,
// A public key your push server will use to send
// messages to client apps via a push server.
applicationServerKey: urlBase64ToUint8Array(_SW_PUBLICKEY_)
};
// Subscribe push notification
@ -257,7 +263,7 @@ export default class MiOS extends EventEmitter {
});
// The path of service worker script
const sw = `/sw.${VERSION}.${LANG}.js`;
const sw = `/sw.${_VERSION_}.${_LANG_}.js`;
// Register service worker
navigator.serviceWorker.register(sw).then(registration => {
@ -310,3 +316,22 @@ export default class MiOS extends EventEmitter {
});
}
}
/**
* Convert the URL safe base64 string to a Uint8Array
* @param base64String base64 string
*/
function urlBase64ToUint8Array(base64String: string): Uint8Array {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}

View file

@ -2,7 +2,7 @@
* API Request
*/
import CONFIG from './config';
declare const _API_URL_: string;
let spinner = null;
let pending = 0;
@ -26,7 +26,7 @@ export default (i, endpoint, data = {}): Promise<{ [x: string]: any }> => {
return new Promise((resolve, reject) => {
// Send request
fetch(endpoint.indexOf('://') > -1 ? endpoint : `${CONFIG.apiUrl}/${endpoint}`, {
fetch(endpoint.indexOf('://') > -1 ? endpoint : `${_API_URL_}/${endpoint}`, {
method: 'POST',
body: JSON.stringify(data),
credentials: endpoint === 'signin' ? 'include' : 'omit'

View file

@ -1,12 +1,12 @@
import MiOS from '../mios';
declare var VERSION: string;
declare const _VERSION_: string;
export default async function(mios: MiOS) {
const meta = await mios.getMeta();
if (meta.version != VERSION) {
if (meta.version != _VERSION_) {
localStorage.setItem('should-refresh', 'true');
alert('%i18n:common.update-available%'.replace('{newer}', meta.version).replace('{current}', VERSION));
alert('%i18n:common.update-available%'.replace('{newer}', meta.version).replace('{current}', _VERSION_));
}
}

View file

@ -1,27 +0,0 @@
const _url = new URL(location.href);
const isRoot = _url.host == 'localhost'
? true
: _url.host.split('.')[0] == 'misskey';
const host = isRoot ? _url.host : _url.host.substring(_url.host.indexOf('.') + 1, _url.host.length);
const scheme = _url.protocol;
const url = `${scheme}//${host}`;
const apiUrl = `${scheme}//api.${host}`;
const chUrl = `${scheme}//ch.${host}`;
const devUrl = `${scheme}//dev.${host}`;
const aboutUrl = `${scheme}//about.${host}`;
const statsUrl = `${scheme}//stats.${host}`;
const statusUrl = `${scheme}//status.${host}`;
export default {
host,
scheme,
url,
apiUrl,
chUrl,
devUrl,
aboutUrl,
statsUrl,
statusUrl
};

View file

@ -1,7 +1,7 @@
import CONFIG from './config';
declare const _HOST_: string;
export default () => {
localStorage.removeItem('me');
document.cookie = `i=; domain=.${CONFIG.host}; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
document.cookie = `i=; domain=.${_HOST_}; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
location.href = '/';
};

View file

@ -1,6 +1,7 @@
declare const _API_URL_: string;
import { EventEmitter } from 'eventemitter3';
import * as ReconnectingWebsocket from 'reconnecting-websocket';
import CONFIG from '../config';
/**
* Misskey stream connection
@ -24,7 +25,7 @@ export default class Connection extends EventEmitter {
this.state = 'initializing';
this.buffer = [];
const host = CONFIG.apiUrl.replace('http', 'ws');
const host = _API_URL_.replace('http', 'ws');
const query = params
? Object.keys(params)
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))

View file

@ -1,6 +1,7 @@
declare const _URL_: string;
import * as riot from 'riot';
import * as pictograph from 'pictograph';
import CONFIG from './config';
const escape = text =>
text
@ -26,7 +27,7 @@ export default (tokens, shouldBreak) => {
case 'link':
return `<a class="link" href="${escape(token.url)}" target="_blank" title="${escape(token.url)}">${escape(token.title)}</a>`;
case 'mention':
return `<a href="${CONFIG.url + '/' + escape(token.username)}" target="_blank" data-user-preview="${token.content}" ${me && me.username == token.username ? 'data-is-me' : ''}>${token.content}</a>`;
return `<a href="${_URL_ + '/' + escape(token.username)}" target="_blank" data-user-preview="${token.content}" ${me && me.username == token.username ? 'data-is-me' : ''}>${token.content}</a>`;
case 'hashtag': // TODO
return `<a>${escape(token.content)}</a>`;
case 'code':

View file

@ -170,8 +170,6 @@
</style>
<script>
import CONFIG from '../../common/scripts/config';
this.on('mount', () => {
this.update({
network: navigator.onLine
@ -193,7 +191,7 @@
});
// Check misskey server is available
fetch(`${CONFIG.apiUrl}/meta`).then(() => {
fetch(`${_API_URL_}/meta`).then(() => {
this.update({
end: true,
server: true

View file

@ -3,7 +3,7 @@
<h1>Misskeyとは</h1>
<p><ruby>Misskey<rt>みすきー</rt></ruby>は、<a href="http://syuilo.com" target="_blank">syuilo</a>が2014年くらいから<a href="https://github.com/syuilo/misskey" target="_blank">オープンソースで</a>開発・運営を行っている、ミニブログベースのSNSです。</p>
<p>無料で誰でも利用でき、広告も掲載していません。</p>
<p><a href={ CONFIG.aboutUrl } target="_blank">もっと知りたい方はこちら</a></p>
<p><a href={ _ABOUT_URL_ } target="_blank">もっと知りたい方はこちら</a></p>
</article>
<style>
:scope

View file

@ -1,5 +1,5 @@
<mk-nav-links>
<a href={ CONFIG.aboutUrl }>%i18n:common.tags.mk-nav-links.about%</a><i></i><a href={ CONFIG.statsUrl }>%i18n:common.tags.mk-nav-links.stats%</a><i></i><a href={ CONFIG.statusUrl }>%i18n:common.tags.mk-nav-links.status%</a><i></i><a href="http://zawazawa.jp/misskey/">%i18n:common.tags.mk-nav-links.wiki%</a><i></i><a href="https://github.com/syuilo/misskey/blob/master/DONORS.md">%i18n:common.tags.mk-nav-links.donors%</a><i></i><a href="https://github.com/syuilo/misskey">%i18n:common.tags.mk-nav-links.repository%</a><i></i><a href={ CONFIG.devUrl }>%i18n:common.tags.mk-nav-links.develop%</a><i></i><a href="https://twitter.com/misskey_xyz" target="_blank">Follow us on <i class="fa fa-twitter"></i></a>
<a href={ _ABOUT_URL_ }>%i18n:common.tags.mk-nav-links.about%</a><i></i><a href={ _STATS_URL_ }>%i18n:common.tags.mk-nav-links.stats%</a><i></i><a href={ _STATUS_URL_ }>%i18n:common.tags.mk-nav-links.status%</a><i></i><a href="http://zawazawa.jp/misskey/">%i18n:common.tags.mk-nav-links.wiki%</a><i></i><a href="https://github.com/syuilo/misskey/blob/master/DONORS.md">%i18n:common.tags.mk-nav-links.donors%</a><i></i><a href="https://github.com/syuilo/misskey">%i18n:common.tags.mk-nav-links.repository%</a><i></i><a href={ _DEV_URL_ }>%i18n:common.tags.mk-nav-links.develop%</a><i></i><a href="https://twitter.com/misskey_xyz" target="_blank">Follow us on <i class="fa fa-twitter"></i></a>
<style>
:scope
display inline

View file

@ -3,7 +3,7 @@
<label class="username">
<p class="caption"><i class="fa fa-at"></i>%i18n:common.tags.mk-signup.username%</p>
<input ref="username" type="text" pattern="^[a-zA-Z0-9-]{3,20}$" placeholder="a~z、A~Z、0~9、-" autocomplete="off" required="required" onkeyup={ onChangeUsername }/>
<p class="profile-page-url-preview" if={ refs.username.value != '' && username-state != 'invalidFormat' && username-state != 'minRange' && username-state != 'maxRange' }>{ CONFIG.url + '/' + refs.username.value }</p>
<p class="profile-page-url-preview" if={ refs.username.value != '' && username-state != 'invalidFormat' && username-state != 'minRange' && username-state != 'maxRange' }>{ _URL_ + '/' + refs.username.value }</p>
<p class="info" if={ usernameState == 'wait' } style="color:#999"><i class="fa fa-fw fa-spinner fa-pulse"></i>%i18n:common.tags.mk-signup.checking%</p>
<p class="info" if={ usernameState == 'ok' } style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>%i18n:common.tags.mk-signup.available%</p>
<p class="info" if={ usernameState == 'unavailable' } style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>%i18n:common.tags.mk-signup.unavailable%</p>
@ -30,7 +30,7 @@
</label>
<label class="recaptcha">
<p class="caption"><i class="fa fa-toggle-on" if={ recaptchaed }></i><i class="fa fa-toggle-off" if={ !recaptchaed }></i>%i18n:common.tags.mk-signup.recaptcha%</p>
<div if={ recaptcha } class="g-recaptcha" data-callback="onRecaptchaed" data-expired-callback="onRecaptchaExpired" data-sitekey={ recaptcha.siteKey }></div>
<div if={ recaptcha } class="g-recaptcha" data-callback="onRecaptchaed" data-expired-callback="onRecaptchaExpired" data-sitekey={ recaptcha.site_key }></div>
</label>
<label class="agree-tou">
<input name="agree-tou" type="checkbox" autocomplete="off" required="required"/>
@ -193,11 +193,9 @@
};
this.on('mount', () => {
fetch('/config.json').then(res => {
res.json().then(conf => {
this.update({
recaptcha: {
siteKey: conf.recaptcha.siteKey
site_key: _RECAPTCHA_SITEKEY_
}
});
@ -206,8 +204,6 @@
script.setAttribute('src', 'https://www.google.com/recaptcha/api.js');
head.appendChild(script);
});
});
});
this.onChangeUsername = () => {
const username = this.refs.username.value;

View file

@ -1,10 +1,10 @@
<mk-twitter-setting>
<p>%i18n:common.tags.mk-twitter-setting.description%<a href={ CONFIG.aboutUrl + '/link-to-twitter' } target="_blank">%i18n:common.tags.mk-twitter-setting.detail%</a></p>
<p>%i18n:common.tags.mk-twitter-setting.description%<a href={ _ABOUT_URL_ + '/link-to-twitter' } target="_blank">%i18n:common.tags.mk-twitter-setting.detail%</a></p>
<p class="account" if={ I.twitter } title={ 'Twitter ID: ' + I.twitter.user_id }>%i18n:common.tags.mk-twitter-setting.connected-to%: <a href={ 'https://twitter.com/' + I.twitter.screen_name } target="_blank">@{ I.twitter.screen_name }</a></p>
<p>
<a href={ CONFIG.apiUrl + '/connect/twitter' } target="_blank" onclick={ connect }>{ I.twitter ? '%i18n:common.tags.mk-twitter-setting.reconnect%' : '%i18n:common.tags.mk-twitter-setting.connect%' }</a>
<a href={ _API_URL_ + '/connect/twitter' } target="_blank" onclick={ connect }>{ I.twitter ? '%i18n:common.tags.mk-twitter-setting.reconnect%' : '%i18n:common.tags.mk-twitter-setting.connect%' }</a>
<span if={ I.twitter }> or </span>
<a href={ CONFIG.apiUrl + '/disconnect/twitter' } target="_blank" if={ I.twitter } onclick={ disconnect }>%i18n:common.tags.mk-twitter-setting.disconnect%</a>
<a href={ _API_URL_ + '/disconnect/twitter' } target="_blank" if={ I.twitter } onclick={ disconnect }>%i18n:common.tags.mk-twitter-setting.disconnect%</a>
</p>
<p class="id" if={ I.twitter }>Twitter ID: { I.twitter.user_id }</p>
<style>
@ -25,8 +25,6 @@
color #8899a6
</style>
<script>
import CONFIG from '../scripts/config';
this.mixin('i');
this.form = null;
@ -47,7 +45,7 @@
this.connect = e => {
e.preventDefault();
this.form = window.open(CONFIG.apiUrl + '/connect/twitter',
this.form = window.open(_API_URL_ + '/connect/twitter',
'twitter_connect_window',
'height=570,width=520');
return false;
@ -55,7 +53,7 @@
this.disconnect = e => {
e.preventDefault();
window.open(CONFIG.apiUrl + '/disconnect/twitter',
window.open(_API_URL_ + '/disconnect/twitter',
'twitter_disconnect_window',
'height=570,width=520');
return false;

View file

@ -172,7 +172,7 @@
if (folder) data.append('folder_id', folder);
const xhr = new XMLHttpRequest();
xhr.open('POST', this.CONFIG.apiUrl + '/drive/files/create', true);
xhr.open('POST', _API_URL_ + '/drive/files/create', true);
xhr.onload = e => {
const driveFile = JSON.parse(e.target.response);

View file

@ -1,7 +1,7 @@
require('fuckadblock');
import dialog from './dialog';
declare var fuckAdBlock: any;
declare const fuckAdBlock: any;
export default () => {
if (fuckAdBlock === undefined) {

View file

@ -1,5 +1,6 @@
declare const _API_URL_: string;
import * as riot from 'riot';
import CONFIG from '../../common/scripts/config';
import dialog from './dialog';
import api from '../../common/scripts/api';
@ -44,7 +45,7 @@ export default (I, cb, file = null) => {
if (folder) data.append('folder_id', folder.id);
const xhr = new XMLHttpRequest();
xhr.open('POST', CONFIG.apiUrl + '/drive/files/create', true);
xhr.open('POST', _API_URL_ + '/drive/files/create', true);
xhr.onload = e => {
const file = JSON.parse((e.target as any).response);
progress.close();

View file

@ -1,5 +1,6 @@
declare const _API_URL_: string;
import * as riot from 'riot';
import CONFIG from '../../common/scripts/config';
import dialog from './dialog';
import api from '../../common/scripts/api';
@ -44,7 +45,7 @@ export default (I, cb, file = null) => {
if (folder) data.append('folder_id', folder.id);
const xhr = new XMLHttpRequest();
xhr.open('POST', CONFIG.apiUrl + '/drive/files/create', true);
xhr.open('POST', _API_URL_ + '/drive/files/create', true);
xhr.onload = e => {
const file = JSON.parse((e.target as any).response);
progress.close();

View file

@ -72,7 +72,7 @@
const length = Math.min(canvW, canvH) / 4;
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
ctx.beginPath();
ctx.strokeStyle = THEME_COLOR;
ctx.strokeStyle = _THEME_COLOR_;
ctx.lineWidth = 2;
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);

View file

@ -28,8 +28,6 @@
</style>
<script>
import CONFIG from '../../../common/scripts/config';
this.mixin('api');
this.folder = this.opts.folder ? this.opts.folder : null;
@ -37,9 +35,9 @@
this.popout = () => {
const folder = this.refs.window.refs.browser.folder;
if (folder) {
return `${CONFIG.url}/i/drive/folder/${folder.id}`;
return `${_URL_}/i/drive/folder/${folder.id}`;
} else {
return `${CONFIG.url}/i/drive`;
return `${_URL_}/i/drive`;
}
};

View file

@ -114,8 +114,8 @@
let broadcasts = [];
if (meta.broadcasts) {
meta.broadcasts.forEach(broadcast => {
if (broadcast[LANG]) {
broadcasts.push(broadcast[LANG]);
if (broadcast[_LANG_]) {
broadcasts.push(broadcast[_LANG_]);
}
});
}

View file

@ -193,7 +193,7 @@
<mk-channel-post>
<header>
<a class="index" onclick={ reply }>{ post.index }:</a>
<a class="name" href={ CONFIG.url + '/' + post.user.username }><b>{ post.user.name }</b></a>
<a class="name" href={ _URL_ + '/' + post.user.username }><b>{ post.user.name }</b></a>
<span>ID:<i>{ post.user.username }</i></span>
</header>
<div>

View file

@ -1,5 +1,5 @@
<mk-version-home-widget>
<p>ver { version } (葵 aoi)</p>
<p>ver { _VERSION_ } (葵 aoi)</p>
<style>
:scope
display block
@ -16,7 +16,5 @@
</style>
<script>
this.mixin('widget');
this.version = VERSION;
</script>
</mk-version-home-widget>

View file

@ -19,11 +19,9 @@
</style>
<script>
import CONFIG from '../../../common/scripts/config';
this.user = this.opts.user;
this.popout = `${CONFIG.url}/i/messaging/${this.user.username}`;
this.popout = `${_URL_}/i/messaging/${this.user.username}`;
this.on('mount', () => {
this.refs.window.on('closed', () => {

View file

@ -150,7 +150,7 @@
</mk-entrance>
<mk-entrance-signin>
<a class="help" href={ CONFIG.aboutUrl + '/help' } title="お困りですか?"><i class="fa fa-question"></i></a>
<a class="help" href={ _ABOUT_URL_ + '/help' } title="お困りですか?"><i class="fa fa-question"></i></a>
<div class="form">
<h1><img if={ user } src={ user.avatar_url + '?thumbnail&size=32' }/>
<p>{ user ? user.name : 'アカウント' }</p>

View file

@ -112,7 +112,7 @@
</header>
<div class="body">
<div class="text" ref="text">
<p class="channel" if={ p.channel != null }><a href={ CONFIG.chUrl + '/' + p.channel.id } target="_blank">{ p.channel.title }</a>:</p>
<p class="channel" if={ p.channel != null }><a href={ _CH_URL_ + '/' + p.channel.id } target="_blank">{ p.channel.title }</a>:</p>
<a class="reply" if={ p.reply }>
<i class="fa fa-reply"></i>
</a>

View file

@ -379,7 +379,7 @@
<ul>
<virtual if={ SIGNIN }>
<li class="home { active: page == 'home' }">
<a href={ CONFIG.url }>
<a href={ _URL_ }>
<i class="fa fa-home"></i>
<p>%i18n:desktop.tags.mk-ui-header-nav.home%</p>
</a>
@ -393,7 +393,7 @@
</li>
</virtual>
<li class="ch">
<a href={ CONFIG.chUrl } target="_blank">
<a href={ _CH_URL_ } target="_blank">
<i class="fa fa-television"></i>
<p>%i18n:desktop.tags.mk-ui-header-nav.ch%</p>
</a>

View file

@ -2,13 +2,12 @@
* App initializer
*/
declare var VERSION: string;
declare var LANG: string;
declare const _VERSION_: string;
declare const _LANG_: string;
declare const _HOST_: string;
import * as riot from 'riot';
import checkForUpdate from './common/scripts/check-for-update';
import mixin from './common/mixins';
import CONFIG from './common/scripts/config';
import MiOS from './common/mios';
require('./common/tags');
@ -16,15 +15,15 @@ require('./common/tags');
* APP ENTRY POINT!
*/
console.info(`Misskey v${VERSION} (葵 aoi)`);
console.info(`Misskey v${_VERSION_} (葵 aoi)`);
if (CONFIG.host != 'localhost') {
document.domain = CONFIG.host;
if (_HOST_ != 'localhost') {
document.domain = _HOST_;
}
{ // Set lang attr
const html = document.documentElement;
html.setAttribute('lang', LANG);
html.setAttribute('lang', _LANG_);
}
{ // Set description meta tag
@ -35,9 +34,6 @@ if (CONFIG.host != 'localhost') {
head.appendChild(meta);
}
// Set global configuration
(riot as any).mixin({ CONFIG });
// iOSでプライベートモードだとlocalStorageが使えないので既存のメソッドを上書きする
try {
localStorage.setItem('kyoppie', 'yuppie');
@ -94,7 +90,7 @@ function panic(e) {
+ '<hr>'
+ `<p>エラーコード: ${e.toString()}</p>`
+ `<p>ブラウザ バージョン: ${navigator.userAgent}</p>`
+ `<p>クライアント バージョン: ${VERSION}</p>`
+ `<p>クライアント バージョン: ${_VERSION_}</p>`
+ '<hr>'
+ '<p>問題が解決しない場合は、上記の情報をお書き添えの上 syuilotan@yahoo.co.jp までご連絡ください。</p>'
+ '<p>Thank you for using Misskey.</p>'

View file

@ -29,7 +29,7 @@
<ul>
<li><a onclick={ signout }><i class="fa fa-power-off"></i>%i18n:mobile.tags.mk-settings-page.signout%</a></li>
</ul>
<p><small>ver { version } (葵 aoi)</small></p>
<p><small>ver { _VERSION_ } (葵 aoi)</small></p>
<style>
:scope
display block
@ -97,7 +97,5 @@
this.signout = signout;
this.mixin('i');
this.version = VERSION;
</script>
</mk-settings>

View file

@ -164,7 +164,7 @@
</header>
<div class="body">
<div class="text" ref="text">
<p class="channel" if={ p.channel != null }><a href={ CONFIG.chUrl + '/' + p.channel.id } target="_blank">{ p.channel.title }</a>:</p>
<p class="channel" if={ p.channel != null }><a href={ _CH_URL_ + '/' + p.channel.id } target="_blank">{ p.channel.title }</a>:</p>
<a class="reply" if={ p.reply }>
<i class="fa fa-reply"></i>
</a>

View file

@ -239,7 +239,7 @@
<li><a href="/i/messaging"><i class="fa fa-comments-o"></i>%i18n:mobile.tags.mk-ui-nav.messaging%<i class="i fa fa-circle" if={ hasUnreadMessagingMessages }></i><i class="fa fa-angle-right"></i></a></li>
</ul>
<ul>
<li><a href={ CONFIG.chUrl } target="_blank"><i class="fa fa-television"></i>%i18n:mobile.tags.mk-ui-nav.ch%<i class="fa fa-angle-right"></i></a></li>
<li><a href={ _CH_URL_ } target="_blank"><i class="fa fa-television"></i>%i18n:mobile.tags.mk-ui-nav.ch%<i class="fa fa-angle-right"></i></a></li>
<li><a href="/i/drive"><i class="fa fa-cloud"></i>%i18n:mobile.tags.mk-ui-nav.drive%<i class="fa fa-angle-right"></i></a></li>
</ul>
<ul>
@ -249,7 +249,7 @@
<li><a href="/i/settings"><i class="fa fa-cog"></i>%i18n:mobile.tags.mk-ui-nav.settings%<i class="fa fa-angle-right"></i></a></li>
</ul>
</div>
<a href={ CONFIG.aboutUrl }><p class="about">%i18n:mobile.tags.mk-ui-nav.about%</p></a>
<a href={ _ABOUT_URL_ }><p class="about">%i18n:mobile.tags.mk-ui-nav.about%</p></a>
</div>
<style>
:scope

View file

@ -4,7 +4,7 @@
<mk-users stats={ stats }/>
<mk-posts stats={ stats }/>
</main>
<footer><a href={ CONFIG.url }>{ CONFIG.host }</a></footer>
<footer><a href={ _URL_ }>{ _HOST_ }</a></footer>
<style>
:scope
display block

View file

@ -5,7 +5,7 @@
<mk-cpu-usage connection={ connection }/>
<mk-mem-usage connection={ connection }/>
</main>
<footer><a href={ CONFIG.url }>{ CONFIG.host }</a></footer>
<footer><a href={ _URL_ }>{ _HOST_ }</a></footer>
<style>
:scope
display block

View file

@ -11,8 +11,6 @@ import * as bodyParser from 'body-parser';
import * as favicon from 'serve-favicon';
import * as compression from 'compression';
import config from '../conf';
/**
* Init app
*/
@ -50,29 +48,7 @@ app.get(/^\/sw\.(.+?)\.js$/, (req, res) => res.sendFile(`${__dirname}/assets/sw.
/**
* Manifest
*/
app.get('/manifest.json', (req, res) => {
const manifest = require((`${__dirname}/assets/manifest.json`));
// Service Worker
if (config.sw) {
manifest['gcm_sender_id'] = config.sw.gcm_sender_id;
}
res.send(manifest);
});
/**
* Serve config
*/
app.get('/config.json', (req, res) => {
const conf = {
recaptcha: {
siteKey: config.recaptcha.siteKey
}
};
res.send(conf);
});
app.get('/manifest.json', (req, res) => res.sendFile(`${__dirname}/assets/manifest.json`));
/**
* Common API

View file

@ -0,0 +1,36 @@
/**
* Replace consts
*/
const StringReplacePlugin = require('string-replace-webpack-plugin');
import version from '../../../src/version';
const constants = require('../../../src/const.json');
import config from '../../../src/conf';
export default lang => {
// 置換の誤爆を防ぐため文字数の多い順に並べてください
const consts = {
_RECAPTCHA_SITEKEY_: JSON.stringify(config.recaptcha.site_key),
_SW_PUBLICKEY_: JSON.stringify(config.sw.public_key),
_THEME_COLOR_: JSON.stringify(constants.themeColor),
_VERSION_: JSON.stringify(version),
_API_URL_: JSON.stringify(config.api_url),
_LANG_: JSON.stringify(lang),
_HOST_: JSON.stringify(config.host),
_URL_: JSON.stringify(config.url),
};
const replacements = Object.keys(consts).map(key => ({
pattern: new RegExp(key, 'g'), replacement: () => consts[key]
}));
return {
enforce: 'post',
test: /\.(tag|js|ts)$/,
exclude: /node_modules/,
loader: StringReplacePlugin.replace({
replacements: replacements
})
};
};

View file

@ -1,4 +1,5 @@
import i18n from './i18n';
import consts from './consts';
import base64 from './base64';
import themeColor from './theme-color';
import tag from './tag';
@ -7,6 +8,7 @@ import typescript from './typescript';
export default (lang, locale) => [
i18n(lang, locale),
consts(lang),
base64(),
themeColor(),
tag(),

View file

@ -1,14 +0,0 @@
/**
* Constant Replacer
*/
import * as webpack from 'webpack';
import version from '../../src/version';
const constants = require('../../src/const.json');
export default lang => new webpack.DefinePlugin({
VERSION: JSON.stringify(version),
LANG: JSON.stringify(lang),
THEME_COLOR: JSON.stringify(constants.themeColor)
});

View file

@ -1,6 +1,5 @@
const StringReplacePlugin = require('string-replace-webpack-plugin');
import constant from './const';
import hoist from './hoist';
//import minify from './minify';
import banner from './banner';
@ -10,7 +9,6 @@ const isProduction = env === 'production';
export default (version, lang) => {
const plugins = [
constant(lang),
new StringReplacePlugin(),
hoist()
];