Instructions for installing mobile apps

Replace the native js dialog with a page telling you how to
download the apps and how to set your HS URL.
pull/7272/head
David Baker 2018-09-03 20:38:30 +01:00
parent 57999b460b
commit 9c8ef4240c
5 changed files with 487 additions and 32 deletions

67
src/vector/getconfig.js Normal file
View File

@ -0,0 +1,67 @@
/*
Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import Promise from 'bluebird';
import request from 'browser-request';
export async function getVectorConfig(relativeLocation) {
if (relativeLocation === undefined) relativeLocation = '';
if (relativeLocation !== '' && !relativeLocation.endsWith('/')) relativeLocation += '/';
try {
const configJson = await getConfig(`${relativeLocation}config.${document.domain}.json`);
// 404s succeed with an empty json config, so check that there are keys
if (Object.keys(configJson).length === 0) {
throw new Error(); // throw to enter the catch
}
return configJson;
} catch (e) {
return await getConfig(relativeLocation + "config.json");
}
}
function getConfig(configJsonFilename) {
let deferred = Promise.defer();
request(
{ method: "GET", url: configJsonFilename },
(err, response, body) => {
if (err || response.status < 200 || response.status >= 300) {
// Lack of a config isn't an error, we should
// just use the defaults.
// Also treat a blank config as no config, assuming
// the status code is 0, because we don't get 404s
// from file: URIs so this is the only way we can
// not fail if the file doesn't exist when loading
// from a file:// URI.
if (response) {
if (response.status == 404 || (response.status == 0 && body == '')) {
deferred.resolve({});
}
}
deferred.reject({err: err, response: response});
return;
}
// We parse the JSON ourselves rather than use the JSON
// parameter, since this throws a parse error on empty
// which breaks if there's no config.json and we're
// loading from the filesystem (see above).
deferred.resolve(JSON.parse(body));
}
);
return deferred.promise;
}

View File

@ -58,6 +58,8 @@ import rageshake from "matrix-react-sdk/lib/rageshake/rageshake";
import CallHandler from 'matrix-react-sdk/lib/CallHandler';
import {getVectorConfig} from './getconfig';
let lastLocationHashSet = null;
function initRageshake() {
@ -238,15 +240,7 @@ async function loadApp() {
let configJson;
let configError;
try {
try {
configJson = await getConfig(`config.${document.domain}.json`);
// 404s succeed with an empty json config, so check that there are keys
if (Object.keys(configJson).length === 0) {
throw new Error(); // throw to enter the catch
}
} catch (e) {
configJson = await getConfig("config.json");
}
configJson = getVectorConfig();
} catch (e) {
configError = e;
}
@ -260,31 +254,13 @@ async function loadApp() {
const preventRedirect = Boolean(fragparts.params.client_secret);
if (!preventRedirect) {
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
// FIXME: ugly status hardcoding
if (SettingsStore.getValue("theme") === 'status') {
window.location = "https://status.im/join-riot.html";
const isIos = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
const isAndroid = /Android/.test(navigator.userAgent);
if (isIos || isAndroid) {
if (!document.cookie.split(';').some((c) => c.startsWith('mobile_redirect_to_guide'))) {
window.location = "mobile_guide/";
return;
}
else {
if (confirm(_t("Riot is not supported on mobile web. Install the app?"))) {
window.location = "https://itunes.apple.com/us/app/vector.im/id1083446067";
return;
}
}
}
else if (/Android/.test(navigator.userAgent)) {
// FIXME: ugly status hardcoding
if (SettingsStore.getValue("theme") === 'status') {
window.location = "https://status.im/join-riot.html";
return;
}
else {
if (confirm(_t("Riot is not supported on mobile web. Install the app?"))) {
window.location = "https://play.google.com/store/apps/details?id=im.vector.alpha";
return;
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,19 @@
import {getVectorConfig} from '../getconfig';
function onBackToRiotClick() {
document.cookie = 'mobile_redirect_to_guide=false;path=/';
window.location.href = '../';
}
async function initPage() {
document.getElementById('back_to_riot_button').onclick = onBackToRiotClick;
const config = await getVectorConfig('..');
let hsUrl = 'https://matrix.org/';
if (config && config['default_hs_url']) {
hsUrl = config['default_hs_url'];
}
document.getElementById('hs_url').innerHTML = hsUrl;
}
initPage();

View File

@ -13,6 +13,8 @@ module.exports = {
"bundle": ["babel-polyfill", "./src/vector/index.js"],
"indexeddb-worker": "./src/vector/indexeddb-worker.js",
"mobileguide": "./src/vector/mobile_guide/index.js",
// We ship olm.js as a separate lump of javascript. This makes it get
// loaded via a separate <script/> tag in index.html (which loads it
// into the browser global `Olm`, where js-sdk expects to find it).
@ -132,6 +134,11 @@ module.exports = {
og_image_url: og_image_url,
},
}),
new HtmlWebpackPlugin({
template: './src/vector/mobile_guide/index.html',
filename: 'mobile_guide/index.html',
chunks: ['mobileguide'],
}),
],
devtool: 'source-map',