parent
							
								
									1809800980
								
							
						
					
					
						commit
						3f8ebac466
					
				
					 46 changed files with 244 additions and 225 deletions
				
			
		|  | @ -22,5 +22,5 @@ elasticsearch: | |||
|   port: 9200 | ||||
|   pass: '' | ||||
| recaptcha: | ||||
|   siteKey: hima | ||||
|   secretKey: saku | ||||
|   site_key: hima | ||||
|   secret_key: saku | ||||
|  |  | |||
|  | @ -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
									
								
							
							
						
						
									
										55
									
								
								docs/config.md
									
										
									
									
									
										Normal 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: | ||||
| 
 | ||||
| ``` | ||||
|  | @ -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` | ||||
|  |  | |||
|  | @ -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` | ||||
|  |  | |||
|  | @ -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?) { | ||||
|  |  | |||
|  | @ -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 = { | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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]; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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_)); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -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 | ||||
| }; | ||||
|  | @ -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 = '/'; | ||||
| }; | ||||
|  |  | |||
|  | @ -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])) | ||||
|  |  | |||
|  | @ -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': | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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,20 +193,16 @@ | |||
| 		}; | ||||
| 
 | ||||
| 		this.on('mount', () => { | ||||
| 			fetch('/config.json').then(res => { | ||||
| 				res.json().then(conf => { | ||||
| 					this.update({ | ||||
| 						recaptcha: { | ||||
| 							siteKey: conf.recaptcha.siteKey | ||||
| 						} | ||||
| 					}); | ||||
| 
 | ||||
| 					const head = document.getElementsByTagName('head')[0]; | ||||
| 					const script = document.createElement('script'); | ||||
| 					script.setAttribute('src', 'https://www.google.com/recaptcha/api.js'); | ||||
| 					head.appendChild(script); | ||||
| 				}); | ||||
| 			this.update({ | ||||
| 				recaptcha: { | ||||
| 					site_key: _RECAPTCHA_SITEKEY_ | ||||
| 				} | ||||
| 			}); | ||||
| 
 | ||||
| 			const head = document.getElementsByTagName('head')[0]; | ||||
| 			const script = document.createElement('script'); | ||||
| 			script.setAttribute('src', 'https://www.google.com/recaptcha/api.js'); | ||||
| 			head.appendChild(script); | ||||
| 		}); | ||||
| 
 | ||||
| 		this.onChangeUsername = () => { | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| require('fuckadblock'); | ||||
| import dialog from './dialog'; | ||||
| 
 | ||||
| declare var fuckAdBlock: any; | ||||
| declare const fuckAdBlock: any; | ||||
| 
 | ||||
| export default () => { | ||||
| 	if (fuckAdBlock === undefined) { | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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`; | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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_]); | ||||
| 						} | ||||
| 					}); | ||||
| 				} | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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', () => { | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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>' | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										36
									
								
								webpack/module/rules/consts.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								webpack/module/rules/consts.ts
									
										
									
									
									
										Normal 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 | ||||
| 		}) | ||||
| 	}; | ||||
| }; | ||||
|  | @ -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(), | ||||
|  |  | |||
|  | @ -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) | ||||
| }); | ||||
|  | @ -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() | ||||
| 	]; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue