Compare commits
178 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
569353f5d4 | ||
|
|
5d4b98d4f6 | ||
|
|
6fcf504a4b | ||
|
|
515f8de2c5 | ||
|
|
2ea69624af | ||
|
|
176f7f1515 | ||
|
|
83353e9419 | ||
|
|
c614bc2356 | ||
|
|
f7f5255378 | ||
|
|
23a0e9a96c | ||
|
|
8b89a1770d | ||
|
|
bfe43d841f | ||
|
|
423a047687 | ||
|
|
cc56ef3abd | ||
|
|
fbcdc5adad | ||
|
|
b75180d959 | ||
|
|
fab50bc1f1 | ||
|
|
cfe7fbb23e | ||
|
|
8477ed2967 | ||
|
|
a1132ca7aa | ||
|
|
6e52ab6182 | ||
|
|
e33e0effa3 | ||
|
|
0788826a71 | ||
|
|
c79c0bd333 | ||
|
|
e4c3a63375 | ||
|
|
a9c8429d2e | ||
|
|
9af8cfd1dc | ||
|
|
93502b3c2a | ||
|
|
46ff43e9ba | ||
|
|
954d56e151 | ||
|
|
f040a72765 | ||
|
|
8b65b96adf | ||
|
|
cf5cf02529 | ||
|
|
26ea8a7494 | ||
|
|
27d83ba440 | ||
|
|
c380e7566a | ||
|
|
81518069ed | ||
|
|
a06eb5dfe1 | ||
|
|
7d3f75ef87 | ||
|
|
54ef2dd39b | ||
|
|
b51101038f | ||
|
|
79ad89c673 | ||
|
|
e7dd6fa714 | ||
|
|
a46a0c0949 | ||
|
|
a13b766bad | ||
|
|
969c7c93d6 | ||
|
|
d1c97d8f9a | ||
|
|
ae8ad6969a | ||
|
|
6d62bf0e25 | ||
|
|
26a27a6de4 | ||
|
|
51cfad5b9f | ||
|
|
ca3399df77 | ||
|
|
c4a3211cfc | ||
|
|
d9f662c06e | ||
|
|
abf21675d5 | ||
|
|
8a17e3543a | ||
|
|
c70ad2fa65 | ||
|
|
8f8b28425d | ||
|
|
6b5bfe24e6 | ||
|
|
ae23664a41 | ||
|
|
bbbb82351f | ||
|
|
67a9b6502b | ||
|
|
fe1b0b5cd8 | ||
|
|
8dade0d84e | ||
|
|
499b1c2e70 | ||
|
|
047b255e14 | ||
|
|
3926e4dd98 | ||
|
|
d5d29c1c92 | ||
|
|
556ff24c5f | ||
|
|
f5d9af9b0b | ||
|
|
3ff0ed52b2 | ||
|
|
4ae6e9fdfd | ||
|
|
b9fc46fa41 | ||
|
|
133f3d24f5 | ||
|
|
241ebe50d2 | ||
|
|
7fda26f268 | ||
|
|
0729d50e47 | ||
|
|
f6cbb708b0 | ||
|
|
8b7692cf3b | ||
|
|
7523251098 | ||
|
|
5b5e6d83d9 | ||
|
|
db70272902 | ||
|
|
78068bfaa0 | ||
|
|
9f7cf463b9 | ||
|
|
9eca0d2fde | ||
|
|
45bb74d8f6 | ||
|
|
07103431a9 | ||
|
|
3588ce7bc5 | ||
|
|
557d4ae4c1 | ||
|
|
563d1dc3f1 | ||
|
|
5a8a41ad50 | ||
|
|
60be24c665 | ||
|
|
4a968cd34f | ||
|
|
0608c67767 | ||
|
|
bd1b06c9b4 | ||
|
|
98f8be45b7 | ||
|
|
641f20a4f6 | ||
|
|
7cbfa228ee | ||
|
|
1c82b7b0c3 | ||
|
|
b7368fa933 | ||
|
|
ecf163d4e7 | ||
|
|
1a72d3134c | ||
|
|
612cad5d9e | ||
|
|
9b1b5b3a4b | ||
|
|
6b1ffaff7a | ||
|
|
ffa24eac84 | ||
|
|
82eb69324d | ||
|
|
eaf61526fb | ||
|
|
47906d23f0 | ||
|
|
2fa05f8d61 | ||
|
|
6bee3f22da | ||
|
|
396ecf6570 | ||
|
|
f9ef5e8498 | ||
|
|
cf9cd503e5 | ||
|
|
0e00f708f1 | ||
|
|
a4abccdcef | ||
|
|
6ace710a65 | ||
|
|
23b99f83ce | ||
|
|
8bc2b4a122 | ||
|
|
2b3ec55850 | ||
|
|
9a203aab67 | ||
|
|
5cc1f62839 | ||
|
|
ad57dd3169 | ||
|
|
0635a344ae | ||
|
|
12dab61a67 | ||
|
|
7ae1a70a8d | ||
|
|
4afec6fb7f | ||
|
|
886475af7e | ||
|
|
4d89e997b3 | ||
|
|
93a6e03f70 | ||
|
|
851f4d4a87 | ||
|
|
f2fa326c0c | ||
|
|
d9b63a482c | ||
|
|
c585d80e3e | ||
|
|
9c8be72574 | ||
|
|
e6551e4590 | ||
|
|
7cdb73d74b | ||
|
|
3d0da059dc | ||
|
|
274536bf13 | ||
|
|
6df1574b8b | ||
|
|
490a696567 | ||
|
|
55fad1910a | ||
|
|
aff2a50cdd | ||
|
|
5bc676a042 | ||
|
|
f5b2a92e84 | ||
|
|
1fcd462660 | ||
|
|
152e3c6258 | ||
|
|
b6d2ba2019 | ||
|
|
53e2ce33b8 | ||
|
|
9493f4a872 | ||
|
|
a32ce4fbf6 | ||
|
|
89533706a8 | ||
|
|
deb7ed660c | ||
|
|
a520f0bfed | ||
|
|
c4fd139586 | ||
|
|
4c8ff0955d | ||
|
|
6592526109 | ||
|
|
3a86e659af | ||
|
|
b032accdfa | ||
|
|
272d36995b | ||
|
|
9302c60b47 | ||
|
|
76880e0de7 | ||
|
|
0ef800073b | ||
|
|
93f148fca3 | ||
|
|
5981887705 | ||
|
|
a4c1aee5ea | ||
|
|
f5ba6fa952 | ||
|
|
3ebd90565c | ||
|
|
b95ad701af | ||
|
|
efc68c078e | ||
|
|
0e6012ad45 | ||
|
|
113533ad61 | ||
|
|
ac9075a82a | ||
|
|
998739a7dc | ||
|
|
8afc9f9a09 | ||
|
|
7a63cfd717 | ||
|
|
7ea6157b67 | ||
|
|
553c53e7e8 |
@@ -19,4 +19,4 @@ node_js:
|
||||
install:
|
||||
# clone the deps with depth 1: we know we will only ever need that one
|
||||
# commit.
|
||||
- scripts/fetch-develop.deps.sh --depth 1 && npm install
|
||||
- scripts/fetch-develop.deps.sh --depth 1 && npm i phantomjs-prebuilt && npm install
|
||||
|
||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,3 +1,13 @@
|
||||
Changes in [0.11.4](https://github.com/vector-im/riot-web/releases/tag/v0.11.4) (2017-06-22)
|
||||
============================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.11.3...v0.11.4)
|
||||
|
||||
* Update matrix-js-sdk and react-sdk to fix a regression where the
|
||||
background indexedb worker was disabled, failures to open indexeddb
|
||||
causing the app to fail to start, a race when starting that could break
|
||||
switching to rooms, and the inability to invite users with mixed case
|
||||
usernames.
|
||||
|
||||
Changes in [0.11.3](https://github.com/vector-im/riot-web/releases/tag/v0.11.3) (2017-06-20)
|
||||
============================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/riot-web/compare/v0.11.2...v0.11.3)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "riot-web",
|
||||
"productName": "Riot",
|
||||
"main": "src/electron-main.js",
|
||||
"version": "0.11.3",
|
||||
"version": "0.11.4",
|
||||
"description": "A feature-rich client for Matrix.org",
|
||||
"author": "Vector Creations Ltd.",
|
||||
"dependencies": {
|
||||
|
||||
@@ -29,6 +29,7 @@ const AutoLaunch = require('auto-launch');
|
||||
const tray = require('./tray');
|
||||
const vectorMenu = require('./vectormenu');
|
||||
const webContentsHandler = require('./webcontents-handler');
|
||||
const updater = require('./updater');
|
||||
|
||||
const windowStateKeeper = require('electron-window-state');
|
||||
|
||||
@@ -46,69 +47,9 @@ try {
|
||||
// Continue with the defaults (ie. an empty config)
|
||||
}
|
||||
|
||||
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
|
||||
const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
|
||||
|
||||
let mainWindow = null;
|
||||
let appQuitting = false;
|
||||
global.appQuitting = false;
|
||||
|
||||
function installUpdate() {
|
||||
// for some reason, quitAndInstall does not fire the
|
||||
// before-quit event, so we need to set the flag here.
|
||||
appQuitting = true;
|
||||
electron.autoUpdater.quitAndInstall();
|
||||
}
|
||||
|
||||
function pollForUpdates() {
|
||||
try {
|
||||
electron.autoUpdater.checkForUpdates();
|
||||
} catch (e) {
|
||||
console.log('Couldn\'t check for update', e);
|
||||
}
|
||||
}
|
||||
|
||||
function startAutoUpdate(updateBaseUrl) {
|
||||
if (updateBaseUrl.slice(-1) !== '/') {
|
||||
updateBaseUrl = updateBaseUrl + '/';
|
||||
}
|
||||
try {
|
||||
// For reasons best known to Squirrel, the way it checks for updates
|
||||
// is completely different between macOS and windows. On macOS, it
|
||||
// hits a URL that either gives it a 200 with some json or
|
||||
// 204 No Content. On windows it takes a base path and looks for
|
||||
// files under that path.
|
||||
if (process.platform === 'darwin') {
|
||||
// include the current version in the URL we hit. Electron doesn't add
|
||||
// it anywhere (apart from the User-Agent) so it's up to us. We could
|
||||
// (and previously did) just use the User-Agent, but this doesn't
|
||||
// rely on NSURLConnection setting the User-Agent to what we expect,
|
||||
// and also acts as a convenient cache-buster to ensure that when the
|
||||
// app updates it always gets a fresh value to avoid update-looping.
|
||||
electron.autoUpdater.setFeedURL(
|
||||
`${updateBaseUrl}macos/?localVersion=${encodeURIComponent(electron.app.getVersion())}`);
|
||||
|
||||
} else if (process.platform === 'win32') {
|
||||
electron.autoUpdater.setFeedURL(`${updateBaseUrl}win32/${process.arch}/`);
|
||||
} else {
|
||||
// Squirrel / electron only supports auto-update on these two platforms.
|
||||
// I'm not even going to try to guess which feed style they'd use if they
|
||||
// implemented it on Linux, or if it would be different again.
|
||||
console.log('Auto update not supported on this platform');
|
||||
}
|
||||
// We check for updates ourselves rather than using 'updater' because we need to
|
||||
// do it in the main process (and we don't really need to check every 10 minutes:
|
||||
// every hour should be just fine for a desktop app)
|
||||
// However, we still let the main window listen for the update events.
|
||||
// We also wait a short time before checking for updates the first time because
|
||||
// of squirrel on windows and it taking a small amount of time to release a
|
||||
// lock file.
|
||||
setTimeout(pollForUpdates, INITIAL_UPDATE_DELAY_MS);
|
||||
setInterval(pollForUpdates, UPDATE_POLL_INTERVAL_MS);
|
||||
} catch (err) {
|
||||
// will fail if running in debug mode
|
||||
console.log('Couldn\'t enable update checking', err);
|
||||
}
|
||||
}
|
||||
|
||||
// handle uncaught errors otherwise it displays
|
||||
// stack traces in popup dialogs, which is terrible (which
|
||||
@@ -120,8 +61,6 @@ process.on('uncaughtException', function(error) {
|
||||
console.log('Unhandled exception', error);
|
||||
});
|
||||
|
||||
electron.ipcMain.on('install_update', installUpdate);
|
||||
|
||||
let focusHandlerAttached = false;
|
||||
electron.ipcMain.on('setBadgeCount', function(ev, count) {
|
||||
electron.app.setBadgeCount(count);
|
||||
@@ -233,7 +172,7 @@ electron.app.on('ready', () => {
|
||||
|
||||
if (vectorConfig.update_base_url) {
|
||||
console.log(`Starting auto update with base URL: ${vectorConfig.update_base_url}`);
|
||||
startAutoUpdate(vectorConfig.update_base_url);
|
||||
updater.start(vectorConfig.update_base_url);
|
||||
} else {
|
||||
console.log('No update_base_url is defined: auto update is disabled');
|
||||
}
|
||||
@@ -246,7 +185,7 @@ electron.app.on('ready', () => {
|
||||
defaultHeight: 768,
|
||||
});
|
||||
|
||||
mainWindow = new electron.BrowserWindow({
|
||||
mainWindow = global.mainWindow = new electron.BrowserWindow({
|
||||
icon: iconPath,
|
||||
show: false,
|
||||
autoHideMenuBar: true,
|
||||
@@ -264,7 +203,7 @@ electron.app.on('ready', () => {
|
||||
mainWindow.hide();
|
||||
|
||||
// Create trayIcon icon
|
||||
tray.create(mainWindow, {
|
||||
tray.create({
|
||||
icon_path: iconPath,
|
||||
brand: vectorConfig.brand || 'Riot',
|
||||
});
|
||||
@@ -276,10 +215,10 @@ electron.app.on('ready', () => {
|
||||
}
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null;
|
||||
mainWindow = global.mainWindow = null;
|
||||
});
|
||||
mainWindow.on('close', (e) => {
|
||||
if (!appQuitting && (tray.hasTray() || process.platform === 'darwin')) {
|
||||
if (!global.appQuitting && (tray.hasTray() || process.platform === 'darwin')) {
|
||||
// On Mac, closing the window just hides it
|
||||
// (this is generally how single-window Mac apps
|
||||
// behave, eg. Mail.app)
|
||||
@@ -302,7 +241,10 @@ electron.app.on('activate', () => {
|
||||
});
|
||||
|
||||
electron.app.on('before-quit', () => {
|
||||
appQuitting = true;
|
||||
global.appQuitting = true;
|
||||
if (mainWindow) {
|
||||
mainWindow.webContents.send('before-quit');
|
||||
}
|
||||
});
|
||||
|
||||
// Set the App User Model ID to match what the squirrel
|
||||
|
||||
@@ -26,17 +26,17 @@ exports.hasTray = function hasTray() {
|
||||
return (trayIcon !== null);
|
||||
};
|
||||
|
||||
exports.create = function(win, config) {
|
||||
exports.create = function(config) {
|
||||
// no trays on darwin
|
||||
if (process.platform === 'darwin' || trayIcon) return;
|
||||
|
||||
const toggleWin = function() {
|
||||
if (win.isVisible() && !win.isMinimized()) {
|
||||
win.hide();
|
||||
if (global.mainWindow.isVisible() && !global.mainWindow.isMinimized()) {
|
||||
global.mainWindow.hide();
|
||||
} else {
|
||||
if (win.isMinimized()) win.restore();
|
||||
if (!win.isVisible()) win.show();
|
||||
win.focus();
|
||||
if (global.mainWindow.isMinimized()) global.mainWindow.restore();
|
||||
if (!global.mainWindow.isVisible()) global.mainWindow.show();
|
||||
global.mainWindow.focus();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -54,41 +54,46 @@ exports.create = function(win, config) {
|
||||
},
|
||||
]);
|
||||
|
||||
trayIcon = new Tray(config.icon_path);
|
||||
const defaultIcon = nativeImage.createFromPath(config.icon_path);
|
||||
|
||||
trayIcon = new Tray(defaultIcon);
|
||||
trayIcon.setToolTip(config.brand);
|
||||
trayIcon.setContextMenu(contextMenu);
|
||||
trayIcon.on('click', toggleWin);
|
||||
|
||||
let lastFavicon = null;
|
||||
win.webContents.on('page-favicon-updated', async function(ev, favicons) {
|
||||
let newFavicon = config.icon_path;
|
||||
if (favicons && favicons.length > 0 && favicons[0].startsWith('data:')) {
|
||||
newFavicon = favicons[0];
|
||||
global.mainWindow.webContents.on('page-favicon-updated', async function(ev, favicons) {
|
||||
if (!favicons || favicons.length <= 0 || !favicons[0].startsWith('data:')) {
|
||||
if (lastFavicon !== null) {
|
||||
win.setIcon(defaultIcon);
|
||||
trayIcon.setImage(defaultIcon);
|
||||
lastFavicon = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to change, shortcut
|
||||
if (newFavicon === lastFavicon) return;
|
||||
lastFavicon = newFavicon;
|
||||
if (favicons[0] === lastFavicon) return;
|
||||
lastFavicon = favicons[0];
|
||||
|
||||
// if its not default we have to construct into nativeImage
|
||||
if (newFavicon !== config.icon_path) {
|
||||
newFavicon = nativeImage.createFromDataURL(favicons[0]);
|
||||
let newFavicon = nativeImage.createFromDataURL(favicons[0]);
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
try {
|
||||
const icoPath = path.join(app.getPath('temp'), 'win32_riot_icon.ico')
|
||||
const icoBuf = await pngToIco(newFavicon.toPNG());
|
||||
fs.writeFileSync(icoPath, icoBuf);
|
||||
newFavicon = icoPath;
|
||||
} catch (e) {console.error(e);}
|
||||
// Windows likes ico's too much.
|
||||
if (process.platform === 'win32') {
|
||||
try {
|
||||
const icoPath = path.join(app.getPath('temp'), 'win32_riot_icon.ico');
|
||||
fs.writeFileSync(icoPath, await pngToIco(newFavicon.toPNG()));
|
||||
newFavicon = nativeImage.createFromPath(icoPath);
|
||||
} catch (e) {
|
||||
console.error("Failed to make win32 ico", e);
|
||||
}
|
||||
}
|
||||
|
||||
trayIcon.setImage(newFavicon);
|
||||
win.setIcon(newFavicon);
|
||||
global.mainWindow.setIcon(newFavicon);
|
||||
});
|
||||
|
||||
win.webContents.on('page-title-updated', function(ev, title) {
|
||||
global.mainWindow.webContents.on('page-title-updated', function(ev, title) {
|
||||
trayIcon.setToolTip(title);
|
||||
});
|
||||
};
|
||||
|
||||
84
electron_app/src/updater.js
Normal file
84
electron_app/src/updater.js
Normal file
@@ -0,0 +1,84 @@
|
||||
const { app, autoUpdater, ipcMain } = require('electron');
|
||||
|
||||
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
|
||||
const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
|
||||
|
||||
function installUpdate() {
|
||||
// for some reason, quitAndInstall does not fire the
|
||||
// before-quit event, so we need to set the flag here.
|
||||
global.appQuitting = true;
|
||||
autoUpdater.quitAndInstall();
|
||||
}
|
||||
|
||||
function pollForUpdates() {
|
||||
try {
|
||||
autoUpdater.checkForUpdates();
|
||||
} catch (e) {
|
||||
console.log('Couldn\'t check for update', e);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {};
|
||||
module.exports.start = function startAutoUpdate(updateBaseUrl) {
|
||||
if (updateBaseUrl.slice(-1) !== '/') {
|
||||
updateBaseUrl = updateBaseUrl + '/';
|
||||
}
|
||||
try {
|
||||
let url;
|
||||
// For reasons best known to Squirrel, the way it checks for updates
|
||||
// is completely different between macOS and windows. On macOS, it
|
||||
// hits a URL that either gives it a 200 with some json or
|
||||
// 204 No Content. On windows it takes a base path and looks for
|
||||
// files under that path.
|
||||
if (process.platform === 'darwin') {
|
||||
// include the current version in the URL we hit. Electron doesn't add
|
||||
// it anywhere (apart from the User-Agent) so it's up to us. We could
|
||||
// (and previously did) just use the User-Agent, but this doesn't
|
||||
// rely on NSURLConnection setting the User-Agent to what we expect,
|
||||
// and also acts as a convenient cache-buster to ensure that when the
|
||||
// app updates it always gets a fresh value to avoid update-looping.
|
||||
url = `${updateBaseUrl}macos/?localVersion=${encodeURIComponent(app.getVersion())}`;
|
||||
|
||||
} else if (process.platform === 'win32') {
|
||||
url = `${updateBaseUrl}win32/${process.arch}/`;
|
||||
} else {
|
||||
// Squirrel / electron only supports auto-update on these two platforms.
|
||||
// I'm not even going to try to guess which feed style they'd use if they
|
||||
// implemented it on Linux, or if it would be different again.
|
||||
console.log('Auto update not supported on this platform');
|
||||
}
|
||||
|
||||
if (url) {
|
||||
autoUpdater.setFeedURL(url);
|
||||
// We check for updates ourselves rather than using 'updater' because we need to
|
||||
// do it in the main process (and we don't really need to check every 10 minutes:
|
||||
// every hour should be just fine for a desktop app)
|
||||
// However, we still let the main window listen for the update events.
|
||||
// We also wait a short time before checking for updates the first time because
|
||||
// of squirrel on windows and it taking a small amount of time to release a
|
||||
// lock file.
|
||||
setTimeout(pollForUpdates, INITIAL_UPDATE_DELAY_MS);
|
||||
setInterval(pollForUpdates, UPDATE_POLL_INTERVAL_MS);
|
||||
}
|
||||
} catch (err) {
|
||||
// will fail if running in debug mode
|
||||
console.log('Couldn\'t enable update checking', err);
|
||||
}
|
||||
}
|
||||
|
||||
ipcMain.on('install_update', installUpdate);
|
||||
ipcMain.on('check_updates', pollForUpdates);
|
||||
|
||||
function ipcChannelSendUpdateStatus(status) {
|
||||
if (global.mainWindow) {
|
||||
global.mainWindow.webContents.send('check_updates', status);
|
||||
}
|
||||
}
|
||||
|
||||
autoUpdater.on('update-available', function() {
|
||||
ipcChannelSendUpdateStatus(true);
|
||||
}).on('update-not-available', function() {
|
||||
ipcChannelSendUpdateStatus(false);
|
||||
}).on('error', function(error) {
|
||||
ipcChannelSendUpdateStatus(error.message);
|
||||
});
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "riot-web",
|
||||
"productName": "Riot",
|
||||
"main": "electron_app/src/electron-main.js",
|
||||
"version": "0.11.3",
|
||||
"version": "0.11.4",
|
||||
"description": "A feature-rich client for Matrix.org",
|
||||
"author": "Vector Creations Ltd.",
|
||||
"repository": {
|
||||
@@ -65,8 +65,8 @@
|
||||
"gfm.css": "^1.1.1",
|
||||
"highlight.js": "^9.0.0",
|
||||
"linkifyjs": "^2.1.3",
|
||||
"matrix-js-sdk": "0.7.12",
|
||||
"matrix-react-sdk": "0.9.6",
|
||||
"matrix-js-sdk": "0.7.13",
|
||||
"matrix-react-sdk": "0.9.7",
|
||||
"modernizr": "^3.1.0",
|
||||
"pako": "^1.0.5",
|
||||
"q": "^1.4.1",
|
||||
|
||||
@@ -158,7 +158,7 @@ module.exports = React.createClass({
|
||||
var eventRedact;
|
||||
if(showEventMeta) {
|
||||
eventRedact = (<div className="mx_ImageView_button" onClick={this.onRedactClick}>
|
||||
{ _t('Redact') }
|
||||
{ _t('Remove') }
|
||||
</div>);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ module.exports = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_MatrixToolbar">
|
||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
|
||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="Warning"/>
|
||||
<div className="mx_MatrixToolbar_content">
|
||||
{ _t('You are not receiving desktop notifications') } <a className="mx_MatrixToolbar_link" onClick={ this.onClick }> { _t('Enable them now') }</a>
|
||||
</div>
|
||||
|
||||
@@ -96,7 +96,7 @@ export default React.createClass({
|
||||
}
|
||||
return (
|
||||
<div className="mx_MatrixToolbar">
|
||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="/!\"/>
|
||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="Warning"/>
|
||||
<div className="mx_MatrixToolbar_content">
|
||||
{_t("A new version of Riot is available.")}
|
||||
</div>
|
||||
|
||||
@@ -20,6 +20,7 @@ import React from 'react';
|
||||
import sdk from 'matrix-react-sdk';
|
||||
import Modal from 'matrix-react-sdk/lib/Modal';
|
||||
import dis from 'matrix-react-sdk/lib/dispatcher';
|
||||
import { _t, _tJsx } from 'matrix-react-sdk/lib/languageHandler';
|
||||
|
||||
export default React.createClass({
|
||||
onUpdateClicked: function() {
|
||||
@@ -33,12 +34,11 @@ export default React.createClass({
|
||||
dis.dispatch({
|
||||
action: 'password_changed',
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
const toolbarClasses = "mx_MatrixToolbar mx_MatrixToolbar_clickable";
|
||||
return (
|
||||
<div className={toolbarClasses} onClick={this.onUpdateClicked}>
|
||||
@@ -49,12 +49,16 @@ export default React.createClass({
|
||||
alt="Warning"
|
||||
/>
|
||||
<div className="mx_MatrixToolbar_content">
|
||||
To return to your account in future you need to <u>set a password</u>
|
||||
{ _tJsx(
|
||||
"To return to your account in future you need to <u>set a password</u>",
|
||||
/<u>(.*?)<\/u>/,
|
||||
(sub) => { return <u>{ sub }</u>; },
|
||||
) }
|
||||
</div>
|
||||
<button className="mx_MatrixToolbar_action">
|
||||
Set Password
|
||||
{ _t("Set Password") }
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
85
src/components/views/globals/UpdateCheckBar.js
Normal file
85
src/components/views/globals/UpdateCheckBar.js
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||
import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
|
||||
import {updateCheckStatusEnum} from '../../../vector/platform/VectorBasePlatform';
|
||||
import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
|
||||
|
||||
const doneStatuses = [
|
||||
updateCheckStatusEnum.ERROR,
|
||||
updateCheckStatusEnum.NOTAVAILABLE,
|
||||
];
|
||||
|
||||
export default React.createClass({
|
||||
propTypes: {
|
||||
status: React.PropTypes.oneOf(Object.values(updateCheckStatusEnum)).isRequired,
|
||||
// Currently for error detail but will be usable for download progress
|
||||
// once that is a thing that squirrel passes through electron.
|
||||
detail: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
detail: '',
|
||||
}
|
||||
},
|
||||
|
||||
getStatusText: function() {
|
||||
switch(this.props.status) {
|
||||
case updateCheckStatusEnum.ERROR:
|
||||
return _t('Error encountered (%(errorDetail)s).', { errorDetail: this.props.detail });
|
||||
case updateCheckStatusEnum.CHECKING:
|
||||
return _t('Checking for an update...');
|
||||
case updateCheckStatusEnum.NOTAVAILABLE:
|
||||
return _t('No update available.');
|
||||
case updateCheckStatusEnum.DOWNLOADING:
|
||||
return _t('Downloading update...');
|
||||
}
|
||||
}
|
||||
,
|
||||
|
||||
hideToolbar: function() {
|
||||
PlatformPeg.get().stopUpdateCheck();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const message = this.getStatusText();
|
||||
const warning = _t('Warning');
|
||||
|
||||
let image;
|
||||
if (doneStatuses.includes(this.props.status)) {
|
||||
image = <img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt={warning}/>;
|
||||
} else {
|
||||
image = <img className="mx_MatrixToolbar_warning" src="img/spinner.gif" width="24" height="23" alt={message}/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_MatrixToolbar">
|
||||
{image}
|
||||
<div className="mx_MatrixToolbar_content">
|
||||
{message}
|
||||
</div>
|
||||
<AccessibleButton className="mx_MatrixToolbar_close" onClick={this.hideToolbar}>
|
||||
<img src="img/cancel.svg" width="18" height="18" />
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -207,5 +207,7 @@
|
||||
"General discussion about Matrix and Riot": "Allgemeine Diskussion über Matrix und Riot",
|
||||
"(HTTP status %(httpStatus)s)": "(HTTP-Status %(httpStatus)s)",
|
||||
"You have successfully set a password and an email address!": "Du hast erfolgreich ein Passwort und eine E-Mail-Adresse gesetzt!",
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Denk daran, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst."
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Denk daran, dass du in den Benutzereinstellungen jederzeit eine E-Mail-Adresse setzen kannst.",
|
||||
"To return to your account in future you need to <u>set a password</u>": "Um in Zukunft zu deinem Konto zurückkehren zu können, musst du <u>ein Passwort setzen</u>",
|
||||
"Set Password": "Setze ein Passwort"
|
||||
}
|
||||
|
||||
@@ -198,5 +198,7 @@
|
||||
"Failed to set Direct Message status of room": "Δεν ήταν δυνατός ο ορισμός της κατάστασης Direct Message του δωματίου",
|
||||
"Support for those using, running and writing other bridges": "Υποστήριξη για τους χρήστες που χρησιμοποιούν ή αναπτύσσουν εφαρμογές ενσωμάτωσης για το Matrix",
|
||||
"You have successfully set a password and an email address!": "Ο κωδικός πρόσβασης και η διεύθυνση ηλεκτρονικής αλληλογραφίας ορίστηκαν επιτυχώς!",
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Να θυμάστε ότι μπορείτε πάντα να ορίσετε μια διεύθυνση ηλεκτρονικής αλληλογραφίας στις ρυθμίσεις χρήστη αν αλλάξετε γνώμη."
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Να θυμάστε ότι μπορείτε πάντα να ορίσετε μια διεύθυνση ηλεκτρονικής αλληλογραφίας στις ρυθμίσεις χρήστη αν αλλάξετε γνώμη.",
|
||||
"To return to your account in future you need to <u>set a password</u>": "Για να επιστρέψετε στον λογαριασμό σας μελλοντικα πρέπει να ορίσετε έναν <u>κωδικό πρόσβασης</u>",
|
||||
"Set Password": "Ορισμός κωδικού πρόσβασης"
|
||||
}
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
"Please Register": "Please Register",
|
||||
"powered by Matrix": "powered by Matrix",
|
||||
"Quote": "Quote",
|
||||
"Redact": "Redact",
|
||||
"Reject": "Reject",
|
||||
"Remove %(name)s from the directory?": "Remove %(name)s from the directory?",
|
||||
"Remove": "Remove",
|
||||
@@ -160,6 +159,11 @@
|
||||
"Today": "Today",
|
||||
"Yesterday": "Yesterday",
|
||||
"OK": "OK",
|
||||
"Warning": "Warning",
|
||||
"Checking for an update...": "Checking for an update...",
|
||||
"Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).",
|
||||
"No update available.": "No update available.",
|
||||
"Downloading update...": "Downloading update...",
|
||||
"You need to be using HTTPS to place a screen-sharing call.": "You need to be using HTTPS to place a screen-sharing call.",
|
||||
"Welcome page": "Welcome page",
|
||||
"With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!",
|
||||
@@ -198,5 +202,7 @@
|
||||
"Please set a password!": "Please set a password!",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.",
|
||||
"You have successfully set a password and an email address!": "You have successfully set a password and an email address!",
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Remember, you can always set an email address in user settings if you change your mind."
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Remember, you can always set an email address in user settings if you change your mind.",
|
||||
"To return to your account in future you need to <u>set a password</u>": "To return to your account in future you need to <u>set a password</u>",
|
||||
"Set Password": "Set Password"
|
||||
}
|
||||
|
||||
@@ -96,7 +96,6 @@
|
||||
"Please Register": "Please Register",
|
||||
"powered by Matrix": "powered by Matrix",
|
||||
"Quote": "Quote",
|
||||
"Redact": "Redact",
|
||||
"Reject": "Reject",
|
||||
"Remove %(name)s from the directory?": "Remove %(name)s from the directory?",
|
||||
"Remove": "Remove",
|
||||
|
||||
@@ -198,5 +198,11 @@
|
||||
"Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Muchas salas ya están disponibles en Matrix, enlazadas a redes existentes (Slack, IRC, Gitter, etc) o independientes. ¡Revisa el directorio!",
|
||||
"You can now return to your account after signing out, and sign in on other devices.": "Ahora puedes regresar a tu cuenta después de cerrar tu sesión, e iniciar sesión en otros dispositivos.",
|
||||
"Please set a password!": "¡Por favor establece una contraseña!",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Esto le permitirá regresar a su cuenta después de cerrar sesión, así como iniciar sesión en otros dispositivos."
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Esto le permitirá regresar a su cuenta después de cerrar sesión, así como iniciar sesión en otros dispositivos.",
|
||||
"Warning": "Advertencia",
|
||||
"Checking for an update...": "Comprobando actualizaciones...",
|
||||
"No update available.": "No hay actualizaciones disponibles.",
|
||||
"Downloading update...": "Descargando actualizaciones...",
|
||||
"To return to your account in future you need to <u>set a password</u>": "Para regresar a su cuenta en el futuro Ud. debe <u>establecer una contraseña</u>",
|
||||
"Set Password": "Establezca la contraseña"
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
"Messages containing <span>keywords</span>": "Az üzenet <span>kulcsszavakat</span> tartalmaz",
|
||||
"%(appName)s via %(browserName)s on %(osName)s": "%(appName)s alkalmazás %(browserName)s böngészőn %(osName)s rendszeren",
|
||||
"A new version of Riot is available.": "Új verzió érhető el a Riot-ból.",
|
||||
"All Rooms": "Minden szoba",
|
||||
"All Rooms": "Minden szobában",
|
||||
"Cancel": "Mégse",
|
||||
"Changelog": "Változások",
|
||||
"Collecting app version information": "Alkalmazás verzió információk összegyűjtése",
|
||||
@@ -148,7 +148,7 @@
|
||||
"Search…": "Keresés…",
|
||||
"Send": "Küld",
|
||||
"Send logs": "Naplók elküldése",
|
||||
"This Room": "Ez a szoba",
|
||||
"This Room": "Ebben a szobában",
|
||||
"Unavailable": "Elérhetetlen",
|
||||
"Unknown device": "Ismeretlen eszköz",
|
||||
"Update": "Frissítés",
|
||||
@@ -198,5 +198,7 @@
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Ezzel visszatérhetsz kijelentkezés után a fiókodhoz és más eszközökkel is be tudsz jelentkezni.",
|
||||
"(HTTP status %(httpStatus)s)": "(HTTP állapot %(httpStatus)s)",
|
||||
"You have successfully set a password and an email address!": "Sikeresen beállítottad a jelszavad és e-mail címed!",
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál."
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Ha meggondolod magad, bármikor beállíthatod az e-mail címed a felhasználói beállításoknál.",
|
||||
"To return to your account in future you need to <u>set a password</u>": "A fiókba való visszalépéshez <u>jelszót</u> kell beállítanod",
|
||||
"Set Password": "Jelszó beállítása"
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"Directory": "목록",
|
||||
"Dismiss": "없애기",
|
||||
"Download this file": "이 파일 받기",
|
||||
"Enable desktop notifications": "데스크탑에서 알림 받기",
|
||||
"Enable desktop notifications": "컴퓨터에서 알림 받기",
|
||||
"Enable email notifications": "이메일로 알림 받기",
|
||||
"Enable notifications for this account": "이 계정의 알림 받기",
|
||||
"Error": "오류",
|
||||
@@ -62,7 +62,7 @@
|
||||
"Remove from Directory": "목록에서 지우기",
|
||||
"Report a bug": "오류 보고하기",
|
||||
"Resend": "다시 보내기",
|
||||
"Riot Desktop on %(platformName)s": "%(platformName)s에서 라이엇 데스크탑",
|
||||
"Riot Desktop on %(platformName)s": "%(platformName)s에서 라이엇 컴퓨터판",
|
||||
"Riot is not supported on mobile web. Install the app?": "라이엇은 모바일 사이트를 지원하지 않아요. 앱을 설치하시겠어요?",
|
||||
"Room directory": "방 목록",
|
||||
"Room not found": "방을 찾지 못했어요",
|
||||
@@ -87,7 +87,7 @@
|
||||
"Waiting for response from server": "서버에서 응답을 기다리는 중",
|
||||
"You cannot delete this image. (%(code)s)": "이 사진을 지우실 수 없어요. (%(code)s)",
|
||||
"You cannot delete this message. (%(code)s)": "이 메시지를 지우실 수 없어요. (%(code)s)",
|
||||
"You are not receiving desktop notifications": "데스크탑 알림을 받지 않고 있어요",
|
||||
"You are not receiving desktop notifications": "컴퓨터 알림을 받지 않고 있어요",
|
||||
"Sunday": "일요일",
|
||||
"Monday": "월요일",
|
||||
"Tuesday": "화요일",
|
||||
@@ -171,7 +171,7 @@
|
||||
"Get started with some tips from Riot Bot!": "라이엇 봇에게 조언을 받고 시작하세요!",
|
||||
"General discussion about Matrix and Riot": "매트릭스와 라이엇에 대한 일반 논의",
|
||||
"Discussion of all things Matrix!": "매트릭스의 모든 것에 대한 토론!",
|
||||
"Riot/Web & Desktop chat": "라이엇/웹 & 데스크탑 대화",
|
||||
"Riot/Web & Desktop chat": "라이엇/웹 & 컴퓨터 이야기",
|
||||
"Riot/iOS & matrix-ios-sdk chat": "라이엇/IOS & matrix-ios-sdk 대화",
|
||||
"Riot/Android & matrix-android-sdk chat": "매트릭스/안드로이드 & matrix-ios-sdk 대화",
|
||||
"Matrix technical discussions": "매트릭스 기술 논의",
|
||||
@@ -198,5 +198,7 @@
|
||||
"You have successfully set a password and an email address!": "비밀번호와 이메일 주소를 설정했어요!",
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "잊지마세요, 마음이 바뀌면 언제라도 사용자 설정에서 이메일 주소를 바꾸실 수 있다는 걸요.",
|
||||
"You are Rioting as a guest. <a>Register</a> or <a>sign in</a> to access more rooms and features!": "손님으로 라이엇에 들어오셨네요. <a>계정을 등록하거나</a> <a>로그인하시고</a> 더 많은 방과 기능을 즐기세요!",
|
||||
"You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "라이엇이 아닌 다른 클라이언트에서 구성하셨을 수도 있어요. 라이엇에서 조정할 수는 없지만 여전히 적용되있을 거에요"
|
||||
"You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "라이엇이 아닌 다른 클라이언트에서 구성하셨을 수도 있어요. 라이엇에서 조정할 수는 없지만 여전히 적용되있을 거에요",
|
||||
"To return to your account in future you need to <u>set a password</u>": "나중에 계정으로 돌아가려면 <u>비밀번호 설정</u>을 해야만 해요",
|
||||
"Set Password": "비밀번호 설정"
|
||||
}
|
||||
|
||||
@@ -198,5 +198,7 @@
|
||||
"Please set a password!": "Proszę, ustaw hasło!",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "To pozwoli Ci powrócić do Twojego konta po wylogowaniu i ponownym zalogowaniu się na innych urządzeniach.",
|
||||
"You have successfully set a password and an email address!": "Z powodzeniem ustawiono hasło i adres e-mail dla Twojego konta!",
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Pamiętaj, że zawsze możesz zmienić swój e-mail lub hasło w panelu ustawień użytkownika."
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Pamiętaj, że zawsze możesz zmienić swój e-mail lub hasło w panelu ustawień użytkownika.",
|
||||
"To return to your account in future you need to <u>set a password</u>": "Aby wrócić do swojego konta w przyszłości musisz <u> ustawić hasło </u>",
|
||||
"Set Password": "Ustaw hasło"
|
||||
}
|
||||
|
||||
@@ -199,5 +199,9 @@
|
||||
"Please set a password!": "Por favor, defina uma senha!",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Isso permitirá que você possa retornar à sua conta após fazer logout, e também fazer login em outros dispositivos.",
|
||||
"(HTTP status %(httpStatus)s)": "(Status HTTP %(httpStatus)s)",
|
||||
"Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat descentralizado, criptografado e colaborativo impulsionado por [matrix]"
|
||||
"Decentralised, encrypted chat & collaboration powered by [matrix]": "Chat descentralizado, criptografado e colaborativo impulsionado por [matrix]",
|
||||
"You have successfully set a password and an email address!": "Você definiu uma senha e um endereço de e-mail com sucesso!",
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Lembre-se: você pode sempre definir um endereço de e-mail nas configurações de usuário, se mudar de ideia.",
|
||||
"To return to your account in future you need to <u>set a password</u>": "Para poder, futuramente, retornar à sua conta, você precisa <u>definir uma senha</u>",
|
||||
"Set Password": "Definir senha"
|
||||
}
|
||||
|
||||
@@ -205,5 +205,7 @@
|
||||
"Co-ordination for Riot/Web translators": "Координирование для переводчиков Riot / Web",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Это позволит Вам вернуться в свою учетную запись после выхода, и войти в систему на других устройствах.",
|
||||
"You have successfully set a password and an email address!": "Пароль и адрес электронной почты успешно сохранены!",
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Помните, Вы всегда можете указать адрес электронной почты в пользовательских настройках, если передумаете."
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "Помните, Вы всегда можете указать адрес электронной почты в пользовательских настройках, если передумаете.",
|
||||
"Set Password": "Задать пароль",
|
||||
"To return to your account in future you need to <u>set a password</u>": "Чтобы в будущем вернутся к вашей учётной записи, вы должны <u>задать пароль</u>"
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
"Riot/Web & Desktop chat": "แชทเกี่ยวกับ Riot บนเว็บและเดสก์ทอป",
|
||||
"Riot/iOS & matrix-ios-sdk chat": "แชทเกี่ยวกับ Riot บน iOS และ matrix-ios-sdk",
|
||||
"Riot/Android & matrix-android-sdk chat": "แชทเกี่ยวกับ Riot บน Android และ matrix-android-sdk",
|
||||
"Matrix technical discussions": "พูดคุยเรื่อง Matrix ทางเทคนิค",
|
||||
"Matrix technical discussions": "พูดคุยเรื่อง Matrix เชิงเทคนิค",
|
||||
"Running Matrix services": "การติดตั้งบริการ Matrix",
|
||||
"Community-run support for Synapse": "ฝ่ายสนับสนุน Synapse โดยชุมชนผู้ใช้",
|
||||
"Admin support for Dendrite": "ฝ่ายสนับสนุน Dendrite จากผู้ดูแล",
|
||||
@@ -182,7 +182,7 @@
|
||||
"Implementing VR services with Matrix": "การอิมพลีเมนต์บริการ VR ด้วย Matrix",
|
||||
"Implementing VoIP services with Matrix": "การอิมพลีเมนต์บริการ VoIP ด้วย Matrix",
|
||||
"Support for those using, running and writing other bridges": "ฝ่ายสนับสนุนสำหรับผู้ใช้หรือพัฒนาตัวเชื่อมอื่น ๆ",
|
||||
"Contributing code to Matrix and Riot": "สมทบโค๊ดกับ Matrix และ Riot",
|
||||
"Contributing code to Matrix and Riot": "สมทบโค๊ดให้ Matrix และ Riot",
|
||||
"Dev chat for the Riot/Web dev team": "แชทสำหรับทีมพัฒนา Riot บนเว็บ",
|
||||
"Dev chat for the Dendrite dev team": "แชทสำหรับทีมพัฒนา Dendrite",
|
||||
"Co-ordination for Riot/Web translators": "แชทสำหรับประสานงานการแปล Riot บนเว็บ",
|
||||
@@ -199,5 +199,12 @@
|
||||
"General discussion about Matrix and Riot": "พูดคุยเรื่องทั่วไป ทั้ง Matrix และ Riot",
|
||||
"(HTTP status %(httpStatus)s)": "(สถานะ HTTP %(httpStatus)s)",
|
||||
"Remember, you can always set an email address in user settings if you change your mind.": "อย่าลืม คุณสามารถตั้งที่อยู่อีเมลในการตั้งค่าผู้ใช้ได้ทุกเมื่อหากคุณเปลี่ยนใจ",
|
||||
"You have successfully set a password and an email address!": "ตั้งรหัสผ่านและที่อยู่อีเมลสำเร็จแล้ว!"
|
||||
"You have successfully set a password and an email address!": "ตั้งรหัสผ่านและที่อยู่อีเมลสำเร็จแล้ว!",
|
||||
"Warning": "คำเตือน",
|
||||
"Checking for an update...": "กำลังตรวจหาอัปเดต...",
|
||||
"Error encountered (%(errorDetail)s).": "เกิดข้อผิดพลาด (%(errorDetail)s)",
|
||||
"No update available.": "ไม่มีอัปเดตที่ใหม่กว่า",
|
||||
"Downloading update...": "กำลังดาวน์โหลดอัปเดต...",
|
||||
"To return to your account in future you need to <u>set a password</u>": "คุณต้อง<u>ตั้งรหัสผ่าน</u>เพื่อจะกลับมาที่บัญชีนี้ในอนาคต",
|
||||
"Set Password": "ตั้งรหัสผ่าน"
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"Collapse panel": "Katlanır panel",
|
||||
"Collecting app version information": "Uygulama sürümü bilgileri toplanıyor",
|
||||
"Collecting logs": "Kayıtlar toplanıyor",
|
||||
"Create new room": "Yeni oda oluştur",
|
||||
"Create new room": "Yeni Oda Oluştur",
|
||||
"Couldn't find a matching Matrix room": "Eşleşen bir Matrix odası bulunamadı",
|
||||
"Custom Server Options": "Özel Sunucu Seçenekleri",
|
||||
"customServer_text": "Farklı bir Ana Sunucu URL'si belirleyerek başka bir Matrix sunucusunda oturum açmak için Özel Sunucu Seçeneklerini kullanabilirsiniz. <br/> Bu , Riot'u mevcut Matrix hesabı ile farklı bir Ana Sunucuda kullanmanıza olanak tanır.<br/> <br/> Ayrıca Özel Kimlik Sunucu'da ayarlayabilirsiniz ama kullanıcıları e-posta adresleriyle veya kendi e-posta adresinizle davet edemezsiniz.",
|
||||
@@ -27,9 +27,9 @@
|
||||
"Describe your problem here.": "Probleminizi burada açıklayın.",
|
||||
"Direct Chat": "Doğrudan Sohbet",
|
||||
"Directory": "Dizin",
|
||||
"Dismiss": "Reddet",
|
||||
"Dismiss": "Uzaklaştır",
|
||||
"Download this file": "Bu dosyayı indir",
|
||||
"Drop here %(toAction)s": "Burayı terket %(toAction)s",
|
||||
"Drop here %(toAction)s": "%(toAction)s'ı buraya bırak",
|
||||
"Enable audible notifications in web client": "Web istemcisinde sesli bildirimleri etkinleştir",
|
||||
"Enable desktop notifications": "Masaüstü bildirimlerini etkinleştir",
|
||||
"Enable email notifications": "E-posta bildirimlerini etkinleştir",
|
||||
@@ -43,11 +43,11 @@
|
||||
"Failed to": "Başaramadı",
|
||||
"Failed to add tag %(tagName)s to room": "%(tagName)s etiketi odaya eklenemedi",
|
||||
"Failed to change settings": "Ayarlar değiştirilemedi",
|
||||
"Failed to forget room %(errCode)s": "Odayı unutma başarısız oldu %(errCode)s",
|
||||
"Failed to forget room %(errCode)s": "Oda unutulması başarısız oldu %(errCode)s",
|
||||
"Failed to update keywords": "Anahtar kelimeler güncellenemedi",
|
||||
"Failed to get protocol list from Home Server": "Ana Sunucu'dan protokol listesi alınamadı",
|
||||
"Failed to get public room list": "Genel odalar listesi alınamadı",
|
||||
"Failed to join the room": "Odaya girilemedi",
|
||||
"Failed to join the room": "Odaya girme başarısız oldu",
|
||||
"Failed to remove tag %(tagName)s from room": "Odadan %(tagName)s etiketi kaldırılamadı",
|
||||
"Failed to send report: ": "Rapor gönderilemedi: ",
|
||||
"Failed to set direct chat tag": "Direkt sohbet etiketi ayarlanamadı",
|
||||
@@ -90,7 +90,7 @@
|
||||
"Notify me for anything else": "Başka herhangi bir şey için bana bildirim yap",
|
||||
"Off": "Kapalı",
|
||||
"On": "Açık",
|
||||
"Operation failed": "Operasyon başarısız",
|
||||
"Operation failed": "Operasyon başarısız oldu",
|
||||
"Permalink": "Kalıcı Bağlantı(permalink)",
|
||||
"Please describe the bug. What did you do? What did you expect to happen? What actually happened?": "Lütfen hatayı tanımlayın. Ne yaptınız ? Ne gerçekleşmesini beklediniz ? Ne gerçekleşti ?",
|
||||
"Please describe the bug and/or send logs.": "Lütfen hatayı tanımlayın ve/veya kayıtları gönderin.",
|
||||
@@ -110,7 +110,7 @@
|
||||
"Riot does not know how to join a room on this network": "Riot bu ağdaki bir odaya nasıl gireceğini bilmiyor",
|
||||
"Riot is not supported on mobile web. Install the app?": "Riot mobil web'de desteklenmiyor . Uygulamayı yükle ?",
|
||||
"Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot geçerli tarayıcınızda mevcut olmayan veya denemelik olan birçok gelişmiş tarayıcı özelliği kullanıyor.",
|
||||
"Room directory": "Oda dizini",
|
||||
"Room directory": "Oda Rehberi",
|
||||
"Room not found": "Oda bulunamadı",
|
||||
"Search": "Ara",
|
||||
"Search…": "Arama…",
|
||||
@@ -120,7 +120,7 @@
|
||||
"Settings": "Ayarlar",
|
||||
"Source URL": "Kaynak URL",
|
||||
"Sorry, your browser is <b>not</b> able to run Riot.": "Üzgünüz , tarayıcınız Riot'u <b> çalıştıramıyor </b>.",
|
||||
"Start chat": "Sohbet başlat",
|
||||
"Start chat": "Sohbet Başlat",
|
||||
"The Home Server may be too old to support third party networks": "Ana Sunucu 3. parti ağları desteklemek için çok eski olabilir",
|
||||
"There are advanced notifications which are not shown here": "Burada gösterilmeyen gelişmiş bildirimler var",
|
||||
"The server may be unavailable or overloaded": "Sunucu kullanılamıyor veya aşırı yüklenmiş olabilir",
|
||||
@@ -133,7 +133,7 @@
|
||||
"Unavailable": "Kullanım dışı",
|
||||
"Unhide Preview": "Önizlemeyi Göster",
|
||||
"Unknown device": "Bilinmeyen aygıt",
|
||||
"unknown error code": "Bilinmeyen hata kodu",
|
||||
"unknown error code": "bilinmeyen hata kodu",
|
||||
"Unnamed room": "İsimsiz oda",
|
||||
"Update": "Güncelleştirme",
|
||||
"Uploaded on %(date)s by %(user)s": "%(user)s tarafında %(date)s e yüklendi",
|
||||
@@ -191,10 +191,10 @@
|
||||
"Dev chat for the Dendrite dev team": "Dendrite Geliştirici Takımı için Geliştirici sohbeti",
|
||||
"Co-ordination for Riot/Web translators": "Riot/Web çevirmenleri için koordinasyon",
|
||||
"Lots of rooms already exist in Matrix, linked to existing networks (Slack, IRC, Gitter etc) or independent. Check out the directory!": "Matrix'te varolan ağlara (Slack , IRC , Gitter vb.) bağlı ya da bağımsız bir çok oda var . Dizini kontrol edin!",
|
||||
"Failed to change password. Is your password correct?": "Şifre değiştirme başarısız oldu . Şifreniz doğru mu ?",
|
||||
"Failed to change password. Is your password correct?": "Şifreniz değiştirilemedi . Şifreniz doğru mu ?",
|
||||
"You have successfully set a password!": "Başarıyla bir şifre ayarladınız!",
|
||||
"You can now return to your account after signing out, and sign in on other devices.": "Şimdi oturumunuzu iptal ettikten sonra başka cihazda oturum açarak hesabınıza dönebilirsiniz.",
|
||||
"Continue": "Devam",
|
||||
"Continue": "Devam Et",
|
||||
"Please set a password!": "Lütfen bir şifre ayarlayın !",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Bu oturumunuzu kapattıktan sonra hesabınıza dönmenizi ve diğer cihazlarda oturum açmanızı sağlar.",
|
||||
"You have successfully set a password and an email address!": "Başarıyla bir şifre ve e-posta adresi ayarladın !",
|
||||
|
||||
@@ -194,5 +194,11 @@
|
||||
"No rooms to show": "Кімнати відсутні",
|
||||
"Noisy": "Шумний",
|
||||
"Unavailable": "Нема в наявності",
|
||||
"Unhide Preview": "Відкрити попередній перегляд"
|
||||
"Unhide Preview": "Відкрити попередній перегляд",
|
||||
"Failed to set Direct Message status of room": "Не вдалось встановити статус прямого спілкування в кімнаті",
|
||||
"Messages containing my display name": "Повідомлення, вміщає моє ім'я",
|
||||
"Running Matrix services": "Запуск служби Matrix",
|
||||
"Set Password": "Задати пароль",
|
||||
"Notifications on the following keywords follow rules which can’t be displayed here:": "Сповіщення з наступних ключових слів дотримуються правил, що не можуть бути показані тут:",
|
||||
"To return to your account in future you need to <u>set a password</u>": "Щоб мати змогу використовувати вашу обліковку у майбутньому, <u>зазначте пароль</u>"
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
@import "./matrix-react-sdk/views/rooms/_SearchableEntityList.scss";
|
||||
@import "./matrix-react-sdk/views/rooms/_TabCompleteBar.scss";
|
||||
@import "./matrix-react-sdk/views/rooms/_TopUnreadMessagesBar.scss";
|
||||
@import "./matrix-react-sdk/views/rooms/_AppsDrawer.scss";
|
||||
@import "./matrix-react-sdk/views/settings/_DevicesPanel.scss";
|
||||
@import "./matrix-react-sdk/views/settings/_IntegrationsManager.scss";
|
||||
@import "./matrix-react-sdk/views/voip/_CallView.scss";
|
||||
|
||||
@@ -102,6 +102,13 @@ limitations under the License.
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.mx_UserSettings_passwordWarning {
|
||||
/* To move the "Sign out" button out of the way */
|
||||
clear: both;
|
||||
color: $warning-color;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.mx_UserSettings_importExportButtons {
|
||||
padding-top: 10px;
|
||||
padding-left: 40px;
|
||||
|
||||
@@ -14,6 +14,10 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MEmoteBody {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.mx_MEmoteBody_sender {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
Copyright 2015, 2016 OpenMarket 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.
|
||||
*/
|
||||
|
||||
.mx_AppsDrawer {
|
||||
}
|
||||
|
||||
.mx_AppsContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_AddWidget_button {
|
||||
order: 2;
|
||||
cursor: pointer;
|
||||
padding-right: 12px;
|
||||
padding: 0;
|
||||
margin: 0 0 5px 0;
|
||||
color: $accent-color;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mx_SetAppURLDialog_input {
|
||||
border-radius: 3px;
|
||||
border: 1px solid $input-border-color;
|
||||
padding: 9px;
|
||||
color: $primary-hairline-color;
|
||||
background-color: $primary-bg-color;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mx_AppTile {
|
||||
width: 50%;
|
||||
margin: 0 5px 2px 0;
|
||||
border: 1px solid $primary-hairline-color;
|
||||
border-radius: 2px;
|
||||
// height: 350px;
|
||||
// display: inline-block;
|
||||
}
|
||||
|
||||
.mx_AppTileFullWidth {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 1px solid $primary-hairline-color;
|
||||
border-radius: 2px;
|
||||
// height: 350px;
|
||||
// display: inline-block;
|
||||
}
|
||||
|
||||
.mx_AppTileMenuBar {
|
||||
// height: 15px;
|
||||
margin: 0;
|
||||
padding: 2px 10px;
|
||||
// background-color: $e2e-verified-color;
|
||||
border-bottom: 1px solid $primary-hairline-color;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.mx_AppTileMenuBarWidgets {
|
||||
float: right;
|
||||
}
|
||||
.mx_AppTileMenuBarWidget {
|
||||
// pointer-events: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_AppTileBody iframe {
|
||||
width: 100%;
|
||||
height: 350px;
|
||||
overflow: hidden;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_CloseAppWidget {
|
||||
}
|
||||
|
||||
.mx_AppTileMenuBarWidgetPadding {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.mx_AppIconTile {
|
||||
background-color: $lightbox-bg-color;
|
||||
border: 1px solid rgba(0, 0, 0, 0);
|
||||
width: 200px;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
margin: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_AppIconTile.mx_AppIconTile_active {
|
||||
color: $accent-color;
|
||||
border-color: $accent-color;
|
||||
}
|
||||
|
||||
.mx_AppIconTile:hover {
|
||||
border: 1px solid $accent-color;
|
||||
box-shadow: 0 0 10px 5px rgba(200,200,200,0.5);
|
||||
}
|
||||
|
||||
.mx_AppIconTile_content {
|
||||
padding: 2px 16px;
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mx_AppIconTile_content h4 {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.mx_AppIconTile_content p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 5px;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.mx_AppIconTile_image {
|
||||
padding: 10px;
|
||||
width: 75%;
|
||||
max-width:100px;
|
||||
max-height:100px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.mx_AppIconTile_imageContainer {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
background-color: white;
|
||||
border-radius: 3px 3px 0 0;
|
||||
height: 155px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
form.mx_Custom_Widget_Form div {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@@ -38,6 +38,7 @@
|
||||
.mx_Autocomplete_Completion_pill {
|
||||
border-radius: 17px;
|
||||
height: 34px;
|
||||
padding: 0px 5px;
|
||||
display: flex;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
@@ -45,10 +46,21 @@
|
||||
color: $primary-fg-color;
|
||||
}
|
||||
|
||||
.mx_Autocomplete_Completion_pill * {
|
||||
.mx_Autocomplete_Completion_pill > * {
|
||||
margin: 0 3px;
|
||||
}
|
||||
|
||||
.mx_Autocomplete_provider_name,
|
||||
.mx_Autocomplete_Completion_title,
|
||||
.mx_Autocomplete_Completion_subtitle,
|
||||
.mx_Autocomplete_Completion_description {
|
||||
/* Ellipsis for long names/subtitles/descriptions*/
|
||||
max-width: 150px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* container for pill-style completions */
|
||||
.mx_Autocomplete_Completion_container_pill {
|
||||
margin: 12px;
|
||||
|
||||
@@ -128,7 +128,8 @@ limitations under the License.
|
||||
.mx_MessageComposer_upload,
|
||||
.mx_MessageComposer_hangup,
|
||||
.mx_MessageComposer_voicecall,
|
||||
.mx_MessageComposer_videocall {
|
||||
.mx_MessageComposer_videocall,
|
||||
.mx_MessageComposer_apps {
|
||||
/*display: table-cell;*/
|
||||
/*vertical-align: middle;*/
|
||||
/*padding-left: 10px;*/
|
||||
@@ -140,7 +141,8 @@ limitations under the License.
|
||||
.mx_MessageComposer_upload object,
|
||||
.mx_MessageComposer_hangup object,
|
||||
.mx_MessageComposer_voicecall object,
|
||||
.mx_MessageComposer_videocall object {
|
||||
.mx_MessageComposer_videocall object,
|
||||
.mx_MessageComposer_apps object {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
13
src/skins/vector/img/edit.svg
Normal file
13
src/skins/vector/img/edit.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||
<g>
|
||||
|
||||
<rect x="178.846" y="92.087" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 224.3476 631.1498)" width="128.085" height="354.049"/>
|
||||
<path d="M471.723,88.393l-48.115-48.114c-11.723-11.724-31.558-10.896-44.304,1.85l-45.202,45.203l90.569,90.568l45.202-45.202
|
||||
C482.616,119.952,483.445,100.116,471.723,88.393z"/>
|
||||
<polygon points="64.021,363.252 32,480 148.737,447.979 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 876 B |
24
src/skins/vector/img/icons-apps-active.svg
Normal file
24
src/skins/vector/img/icons-apps-active.svg
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="35px"
|
||||
height="35px" viewBox="0 0 35 35" enable-background="new 0 0 35 35" xml:space="preserve">
|
||||
<g id="Layer_1">
|
||||
<path id="Oval-109-Copy" fill="#76CFA6" enable-background="new " d="M17.5,35C27.165,35,35,27.165,35,17.5S27.165,0,17.5,0
|
||||
S0,7.835,0,17.5S7.835,35,17.5,35z"/>
|
||||
<g id="Icon">
|
||||
<g>
|
||||
<path fill="none" stroke="#FFFFFF" d="M7.5,12.5h5v-5h-5V12.5z M15,27.5h5v-5h-5V27.5z M7.5,27.5h5v-5h-5V27.5z M7.5,20h5v-5h-5
|
||||
V20z M15,20h5v-5h-5V20z M22.5,7.5v5h5v-5H22.5z M15,12.5h5v-5h-5V12.5z M22.5,20h5v-5h-5V20z M22.5,27.5h5v-5h-5V27.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Layer_2">
|
||||
<g id="Icon_1_" opacity="0.15">
|
||||
<g>
|
||||
<path fill="none" stroke="#76CFA6" d="M7.5,12.5h5v-5h-5V12.5z M15,27.5h5v-5h-5V27.5z M7.5,27.5h5v-5h-5V27.5z M7.5,20h5v-5h-5
|
||||
V20z M15,20h5v-5h-5V20z M22.5,7.5v5h5v-5H22.5z M15,12.5h5v-5h-5V12.5z M22.5,20h5v-5h-5V20z M22.5,27.5h5v-5h-5V27.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
14
src/skins/vector/img/icons-apps.svg
Normal file
14
src/skins/vector/img/icons-apps.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="35px" height="35px" viewBox="0 0 35 35" enable-background="new 0 0 35 35" xml:space="preserve">
|
||||
<path id="Oval-109-Copy" opacity="0.15" fill="#76CFA6" enable-background="new " d="M17.5,35C27.165,35,35,27.165,35,17.5
|
||||
S27.165,0,17.5,0S0,7.835,0,17.5S7.835,35,17.5,35z"/>
|
||||
<g id="Icon">
|
||||
<g>
|
||||
<path fill="none" stroke="#76CFA6" d="M7.5,12.5h5v-5h-5V12.5z M15,27.5h5v-5h-5V27.5z M7.5,27.5h5v-5h-5V27.5z M7.5,20h5v-5h-5
|
||||
V20z M15,20h5v-5h-5V20z M22.5,7.5v5h5v-5H22.5z M15,12.5h5v-5h-5V12.5z M22.5,20h5v-5h-5V20z M22.5,27.5h5v-5h-5V27.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 941 B |
@@ -45,6 +45,12 @@ rageshake.init().then(() => {
|
||||
console.error("Failed to initialise rageshake: " + err);
|
||||
});
|
||||
|
||||
window.addEventListener('beforeunload', (e) => {
|
||||
console.log('riot-web closing');
|
||||
// try to flush the logs to indexeddb
|
||||
rageshake.flush();
|
||||
});
|
||||
|
||||
|
||||
// add React and ReactPerf to the global namespace, to make them easier to
|
||||
// access via the console
|
||||
@@ -59,7 +65,6 @@ var sdk = require("matrix-react-sdk");
|
||||
const PlatformPeg = require("matrix-react-sdk/lib/PlatformPeg");
|
||||
sdk.loadSkin(require('../component-index'));
|
||||
var VectorConferenceHandler = require('../VectorConferenceHandler');
|
||||
var UpdateChecker = require("./updater");
|
||||
var q = require('q');
|
||||
var request = require('browser-request');
|
||||
import * as UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore';
|
||||
@@ -216,18 +221,16 @@ function getConfig() {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onLoadCompleted() {
|
||||
function onTokenLoginCompleted() {
|
||||
// if we did a token login, we're now left with the token, hs and is
|
||||
// url as query params in the url; a little nasty but let's redirect to
|
||||
// clear them.
|
||||
if (window.location.search) {
|
||||
var parsedUrl = url.parse(window.location.href);
|
||||
parsedUrl.search = "";
|
||||
var formatted = url.format(parsedUrl);
|
||||
console.log("Redirecting to " + formatted + " to drop loginToken " +
|
||||
"from queryparams");
|
||||
window.location.href = formatted;
|
||||
}
|
||||
var parsedUrl = url.parse(window.location.href);
|
||||
parsedUrl.search = "";
|
||||
var formatted = url.format(parsedUrl);
|
||||
console.log("Redirecting to " + formatted + " to drop loginToken " +
|
||||
"from queryparams");
|
||||
window.location.href = formatted;
|
||||
}
|
||||
|
||||
async function loadApp() {
|
||||
@@ -277,7 +280,9 @@ async function loadApp() {
|
||||
Unable to load config file: please refresh the page to try again.
|
||||
</div>, document.getElementById('matrixchat'));
|
||||
} else if (validBrowser) {
|
||||
UpdateChecker.start();
|
||||
const platform = PlatformPeg.get();
|
||||
platform.startUpdater();
|
||||
|
||||
const MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||
window.matrixChat = ReactDOM.render(
|
||||
<MatrixChat
|
||||
@@ -288,9 +293,9 @@ async function loadApp() {
|
||||
realQueryParams={params}
|
||||
startingFragmentQueryParams={fragparts.params}
|
||||
enableGuest={true}
|
||||
onLoadCompleted={onLoadCompleted}
|
||||
onTokenLoginCompleted={onTokenLoginCompleted}
|
||||
initialScreenAfterLogin={getScreenFromLocation(window.location)}
|
||||
defaultDeviceDisplayName={PlatformPeg.get().getDefaultDeviceDisplayName()}
|
||||
defaultDeviceDisplayName={platform.getDefaultDeviceDisplayName()}
|
||||
/>,
|
||||
document.getElementById('matrixchat')
|
||||
);
|
||||
|
||||
@@ -17,14 +17,21 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import VectorBasePlatform from './VectorBasePlatform';
|
||||
import VectorBasePlatform, {updateCheckStatusEnum} from './VectorBasePlatform';
|
||||
import dis from 'matrix-react-sdk/lib/dispatcher';
|
||||
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||
import q from 'q';
|
||||
import electron, {remote, ipcRenderer} from 'electron';
|
||||
import {remote, ipcRenderer} from 'electron';
|
||||
import rageshake from '../rageshake';
|
||||
|
||||
remote.autoUpdater.on('update-downloaded', onUpdateDownloaded);
|
||||
|
||||
// try to flush the rageshake logs to indexeddb before quit.
|
||||
ipcRenderer.on('before-quit', function () {
|
||||
console.log('riot-desktop closing');
|
||||
rageshake.flush();
|
||||
});
|
||||
|
||||
function onUpdateDownloaded(ev: Event, releaseNotes: string, ver: string, date: Date, updateURL: string) {
|
||||
dis.dispatch({
|
||||
action: 'new_version',
|
||||
@@ -62,10 +69,42 @@ function _onAction(payload: Object) {
|
||||
}
|
||||
}
|
||||
|
||||
function getUpdateCheckStatus(status) {
|
||||
if (status === true) {
|
||||
return { status: updateCheckStatusEnum.DOWNLOADING };
|
||||
} else if (status === false) {
|
||||
return { status: updateCheckStatusEnum.NOTAVAILABLE };
|
||||
} else {
|
||||
return {
|
||||
status: updateCheckStatusEnum.ERROR,
|
||||
detail: status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default class ElectronPlatform extends VectorBasePlatform {
|
||||
constructor() {
|
||||
super();
|
||||
dis.register(_onAction);
|
||||
this.updatable = Boolean(remote.autoUpdater.getFeedURL());
|
||||
|
||||
/*
|
||||
IPC Call `check_updates` returns:
|
||||
true if there is an update available
|
||||
false if there is not
|
||||
or the error if one is encountered
|
||||
*/
|
||||
ipcRenderer.on('check_updates', (event, status) => {
|
||||
if (!this.showUpdateCheck) return;
|
||||
dis.dispatch({
|
||||
action: 'check_updates',
|
||||
value: getUpdateCheckStatus(status),
|
||||
});
|
||||
this.showUpdateCheck = false;
|
||||
});
|
||||
|
||||
this.startUpdateCheck = this.startUpdateCheck.bind(this);
|
||||
this.stopUpdateCheck = this.stopUpdateCheck.bind(this);
|
||||
}
|
||||
|
||||
getHumanReadableName(): string {
|
||||
@@ -137,17 +176,18 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||
return q(remote.app.getVersion());
|
||||
}
|
||||
|
||||
pollForUpdate() {
|
||||
// In electron we control the update process ourselves, since
|
||||
// it needs to run in the main process, so we just run the timer
|
||||
// loop in the main electron process instead.
|
||||
startUpdateCheck() {
|
||||
if (this.showUpdateCheck) return;
|
||||
super.startUpdateCheck();
|
||||
|
||||
ipcRenderer.send('check_updates');
|
||||
}
|
||||
|
||||
installUpdate() {
|
||||
// IPC to the main process to install the update, since quitAndInstall
|
||||
// doesn't fire the before-quit event so the main process needs to know
|
||||
// it should exit.
|
||||
electron.ipcRenderer.send('install_update');
|
||||
ipcRenderer.send('install_update');
|
||||
}
|
||||
|
||||
getDefaultDeviceDisplayName(): string {
|
||||
|
||||
@@ -19,9 +19,18 @@ limitations under the License.
|
||||
|
||||
import BasePlatform from 'matrix-react-sdk/lib/BasePlatform';
|
||||
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||
import dis from 'matrix-react-sdk/lib/dispatcher';
|
||||
|
||||
import Favico from 'favico.js';
|
||||
|
||||
export const updateCheckStatusEnum = {
|
||||
CHECKING: 'CHECKING',
|
||||
ERROR: 'ERROR',
|
||||
NOTAVAILABLE: 'NOTAVAILABLE',
|
||||
DOWNLOADING: 'DOWNLOADING',
|
||||
READY: 'READY',
|
||||
};
|
||||
|
||||
/**
|
||||
* Vector-specific extensions to the BasePlatform template
|
||||
*/
|
||||
@@ -34,7 +43,12 @@ export default class VectorBasePlatform extends BasePlatform {
|
||||
// and we set the state each time, even if the value hasn't changed,
|
||||
// so we'd need to fix that if enabling the animation.
|
||||
this.favicon = new Favico({animation: 'none'});
|
||||
this.showUpdateCheck = false;
|
||||
this._updateFavicon();
|
||||
this.updatable = true;
|
||||
|
||||
this.startUpdateCheck = this.startUpdateCheck.bind(this);
|
||||
this.stopUpdateCheck = this.stopUpdateCheck.bind(this);
|
||||
}
|
||||
|
||||
getHumanReadableName(): string {
|
||||
@@ -75,12 +89,32 @@ export default class VectorBasePlatform extends BasePlatform {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for the availability of an update to the version of the
|
||||
* app that's currently running.
|
||||
* If an update is available, this function should dispatch the
|
||||
* 'new_version' action.
|
||||
* Begin update polling, if applicable
|
||||
*/
|
||||
pollForUpdate() {
|
||||
startUpdater() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we can call checkForUpdate on this platform build
|
||||
*/
|
||||
canSelfUpdate(): boolean {
|
||||
return this.updatable;
|
||||
}
|
||||
|
||||
startUpdateCheck() {
|
||||
this.showUpdateCheck = true;
|
||||
dis.dispatch({
|
||||
action: 'check_updates',
|
||||
value: { status: updateCheckStatusEnum.CHECKING },
|
||||
});
|
||||
}
|
||||
|
||||
stopUpdateCheck() {
|
||||
this.showUpdateCheck = false;
|
||||
dis.dispatch({
|
||||
action: 'check_updates',
|
||||
value: false,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import VectorBasePlatform from './VectorBasePlatform';
|
||||
import VectorBasePlatform, {updateCheckStatusEnum} from './VectorBasePlatform';
|
||||
import request from 'browser-request';
|
||||
import dis from 'matrix-react-sdk/lib/dispatcher.js';
|
||||
import { _t } from 'matrix-react-sdk/lib/languageHandler';
|
||||
@@ -26,10 +26,15 @@ import q from 'q';
|
||||
import url from 'url';
|
||||
import UAParser from 'ua-parser-js';
|
||||
|
||||
var POKE_RATE_MS = 10 * 60 * 1000; // 10 min
|
||||
|
||||
export default class WebPlatform extends VectorBasePlatform {
|
||||
constructor() {
|
||||
super();
|
||||
this.runningVersion = null;
|
||||
|
||||
this.startUpdateCheck = this.startUpdateCheck.bind(this);
|
||||
this.stopUpdateCheck = this.stopUpdateCheck.bind(this);
|
||||
}
|
||||
|
||||
getHumanReadableName(): string {
|
||||
@@ -132,8 +137,13 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||
return this._getVersion();
|
||||
}
|
||||
|
||||
startUpdater() {
|
||||
this.pollForUpdate();
|
||||
setInterval(this.pollForUpdate.bind(this), POKE_RATE_MS);
|
||||
}
|
||||
|
||||
pollForUpdate() {
|
||||
this._getVersion().done((ver) => {
|
||||
return this._getVersion().then((ver) => {
|
||||
if (this.runningVersion === null) {
|
||||
this.runningVersion = ver;
|
||||
} else if (this.runningVersion !== ver) {
|
||||
@@ -142,9 +152,29 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||
currentVersion: this.runningVersion,
|
||||
newVersion: ver,
|
||||
});
|
||||
// Return to skip a MatrixChat state update
|
||||
return;
|
||||
}
|
||||
return { status: updateCheckStatusEnum.NOTAVAILABLE };
|
||||
}, (err) => {
|
||||
console.error("Failed to poll for update", err);
|
||||
return {
|
||||
status: updateCheckStatusEnum.ERROR,
|
||||
detail: err.message || err.status ? err.status.toString() : 'Unknown Error',
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
startUpdateCheck() {
|
||||
if (this.showUpdateCheck) return;
|
||||
super.startUpdateCheck();
|
||||
this.pollForUpdate().then((updateState) => {
|
||||
if (!this.showUpdateCheck) return;
|
||||
if (!updateState) return;
|
||||
dis.dispatch({
|
||||
action: 'check_updates',
|
||||
value: updateState,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -410,8 +410,16 @@ module.exports = {
|
||||
}
|
||||
logger = new ConsoleLogger();
|
||||
logger.monkeyPatch(window.console);
|
||||
if (window.indexedDB) {
|
||||
store = new IndexedDBLogStore(window.indexedDB, logger);
|
||||
|
||||
// just *accessing* indexedDB throws an exception in firefox with
|
||||
// indexeddb disabled.
|
||||
let indexedDB;
|
||||
try {
|
||||
indexedDB = window.indexedDB;
|
||||
} catch(e) {}
|
||||
|
||||
if (indexedDB) {
|
||||
store = new IndexedDBLogStore(indexedDB, logger);
|
||||
initPromise = store.connect();
|
||||
return initPromise;
|
||||
}
|
||||
@@ -419,6 +427,13 @@ module.exports = {
|
||||
return initPromise;
|
||||
},
|
||||
|
||||
flush: function() {
|
||||
if (!store) {
|
||||
return;
|
||||
}
|
||||
store.flush();
|
||||
},
|
||||
|
||||
/**
|
||||
* Clean up old logs.
|
||||
* @return Promise Resolves if cleaned logs.
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 OpenMarket 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 PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
|
||||
|
||||
var POKE_RATE_MS = 10 * 60 * 1000; // 10 min
|
||||
|
||||
module.exports = {
|
||||
start: function() {
|
||||
module.exports.poll();
|
||||
setInterval(module.exports.poll, POKE_RATE_MS);
|
||||
},
|
||||
|
||||
poll: function() {
|
||||
PlatformPeg.get().pollForUpdate();
|
||||
}
|
||||
};
|
||||
@@ -29,6 +29,8 @@ import jssdk from 'matrix-js-sdk';
|
||||
import sdk from 'matrix-react-sdk';
|
||||
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
|
||||
import * as languageHandler from 'matrix-react-sdk/lib/languageHandler';
|
||||
import {VIEWS} from 'matrix-react-sdk/lib/components/structures/MatrixChat';
|
||||
import dis from 'matrix-react-sdk/lib/dispatcher';
|
||||
|
||||
import * as test_utils from '../test-utils';
|
||||
import MockHttpBackend from '../mock-request';
|
||||
@@ -47,8 +49,8 @@ describe('loading:', function () {
|
||||
// the mounted MatrixChat
|
||||
let matrixChat;
|
||||
|
||||
// a promise which resolves when the MatrixChat calls onLoadCompleted
|
||||
let loadCompletePromise;
|
||||
// a promise which resolves when the MatrixChat calls onTokenLoginCompleted
|
||||
let tokenLoginCompletePromise;
|
||||
|
||||
beforeEach(function() {
|
||||
test_utils.beforeEach(this);
|
||||
@@ -68,7 +70,8 @@ describe('loading:', function () {
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async function() {
|
||||
afterEach(async function () {
|
||||
console.log(`${Date.now()}: loading: afterEach`);
|
||||
if (parentDiv) {
|
||||
ReactDOM.unmountComponentAtNode(parentDiv);
|
||||
parentDiv.remove();
|
||||
@@ -81,6 +84,7 @@ describe('loading:', function () {
|
||||
// clear the indexeddbs so we can start from a clean slate next time.
|
||||
await test_utils.deleteIndexedDB('matrix-js-sdk:crypto');
|
||||
await test_utils.deleteIndexedDB('matrix-js-sdk:riot-web-sync');
|
||||
console.log(`${Date.now()}: loading: afterEach complete`);
|
||||
});
|
||||
|
||||
/* simulate the load process done by index.js
|
||||
@@ -99,8 +103,8 @@ describe('loading:', function () {
|
||||
toString: function() { return this.search + this.hash; },
|
||||
};
|
||||
|
||||
let loadCompleteDefer = q.defer();
|
||||
loadCompletePromise = loadCompleteDefer.promise;
|
||||
let tokenLoginCompleteDefer = q.defer();
|
||||
tokenLoginCompletePromise = tokenLoginCompleteDefer.promise;
|
||||
|
||||
function onNewScreen(screen) {
|
||||
console.log(Date.now() + " newscreen "+screen);
|
||||
@@ -135,7 +139,7 @@ describe('loading:', function () {
|
||||
realQueryParams={params}
|
||||
startingFragmentQueryParams={fragParts.params}
|
||||
enableGuest={true}
|
||||
onLoadCompleted={loadCompleteDefer.resolve}
|
||||
onTokenLoginCompleted={tokenLoginCompleteDefer.resolve}
|
||||
initialScreenAfterLogin={getScreenFromLocation(windowLocation)}
|
||||
makeRegistrationUrl={() => {throw new Error('Not implemented');}}
|
||||
/>, parentDiv
|
||||
@@ -153,8 +157,8 @@ describe('loading:', function () {
|
||||
.check((r) => {syncRequest = r;})
|
||||
.respond(200, response);
|
||||
|
||||
console.log("waiting for /sync");
|
||||
for (let attempts = 10; attempts > 0; attempts--) {
|
||||
console.log(Date.now() + " waiting for /sync");
|
||||
if (syncRequest) {
|
||||
return syncRequest;
|
||||
}
|
||||
@@ -179,12 +183,12 @@ describe('loading:', function () {
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// Wait for another trip around the event loop for the UI to update
|
||||
return q.delay(1);
|
||||
return q.delay(10);
|
||||
}).then(() => {
|
||||
// we expect a single <Login> component following session load
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.login.Login'));
|
||||
expect(windowLocation.hash).toEqual("");
|
||||
expect(windowLocation.hash).toEqual("#/login");
|
||||
}).done(done, done);
|
||||
});
|
||||
|
||||
@@ -205,7 +209,7 @@ describe('loading:', function () {
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// Wait for another trip around the event loop for the UI to update
|
||||
return q.delay(1);
|
||||
return q.delay(10);
|
||||
}).then(() => {
|
||||
return completeLogin(matrixChat);
|
||||
}).then(() => {
|
||||
@@ -360,6 +364,9 @@ describe('loading:', function () {
|
||||
loadApp({
|
||||
uriFragment: "#/login",
|
||||
});
|
||||
|
||||
// give the UI a chance to display
|
||||
return q.delay(50);
|
||||
});
|
||||
|
||||
it('shows a login view', function() {
|
||||
@@ -489,6 +496,76 @@ describe('loading:', function () {
|
||||
expect(windowLocation.hash).toEqual("#/room/!room:id");
|
||||
}).done(done, done);
|
||||
});
|
||||
|
||||
describe('Login as user', function() {
|
||||
beforeEach(function() {
|
||||
// first we have to load the homepage
|
||||
loadApp();
|
||||
|
||||
httpBackend.when('POST', '/register').check(function(req) {
|
||||
expect(req.queryParams.kind).toEqual('guest');
|
||||
}).respond(200, {
|
||||
user_id: "@guest:localhost",
|
||||
access_token: "secret_token",
|
||||
});
|
||||
|
||||
return httpBackend.flush().then(() => {
|
||||
return awaitSyncingSpinner(matrixChat);
|
||||
}).then(() => {
|
||||
// we got a sync spinner - let the sync complete
|
||||
return expectAndAwaitSync();
|
||||
}).then(() => {
|
||||
// once the sync completes, we should have a home page
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.HomePage'));
|
||||
|
||||
// we simulate a click on the 'login' button by firing off
|
||||
// the relevant dispatch.
|
||||
//
|
||||
// XXX: is it an anti-pattern to access the react-sdk's
|
||||
// dispatcher in this way? Is it better to find the login
|
||||
// button and simulate a click? (we might have to arrange
|
||||
// for it to be shown - it's not always, due to the
|
||||
// collapsing left panel
|
||||
|
||||
dis.dispatch({ action: 'start_login' });
|
||||
|
||||
return q.delay(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('should give us a login page', function() {
|
||||
expect(windowLocation.hash).toEqual("#/login");
|
||||
|
||||
// we expect a single <Login> component
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.login.Login')
|
||||
);
|
||||
});
|
||||
|
||||
it('should allow us to return to the app', function() {
|
||||
const login = ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.login.Login')
|
||||
);
|
||||
|
||||
const linkText = 'Return to app';
|
||||
|
||||
const returnToApp = ReactTestUtils.scryRenderedDOMComponentsWithTag(
|
||||
login, 'a').find((e) => e.innerText === linkText);
|
||||
|
||||
if (!returnToApp) {
|
||||
throw new Error(`Couldn't find '${linkText}' link`);
|
||||
}
|
||||
|
||||
ReactTestUtils.Simulate.click(returnToApp);
|
||||
|
||||
return q.delay(1).then(() => {
|
||||
// we should be straight back into the home page
|
||||
ReactTestUtils.findRenderedComponentWithType(
|
||||
matrixChat, sdk.getComponent('structures.HomePage'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Token login:', function() {
|
||||
@@ -513,12 +590,12 @@ describe('loading:', function () {
|
||||
|
||||
return httpBackend.flush();
|
||||
}).then(() => {
|
||||
// at this point, MatrixChat should fire onLoadCompleted, which
|
||||
// at this point, MatrixChat should fire onTokenLoginCompleted, which
|
||||
// makes index.js reload the app. We're not going to attempt to
|
||||
// simulate the reload - just check that things are left in the
|
||||
// right state for the reloaded app.
|
||||
|
||||
return loadCompletePromise;
|
||||
return tokenLoginCompletePromise;
|
||||
}).then(() => {
|
||||
// check that the localstorage has been set up in such a way that
|
||||
// the reloaded app can pick up where we leave off.
|
||||
@@ -539,7 +616,6 @@ describe('loading:', function () {
|
||||
matrixChat, sdk.getComponent('structures.login.Login'));
|
||||
|
||||
httpBackend.when('POST', '/login').check(function(req) {
|
||||
console.log(req);
|
||||
expect(req.data.type).toEqual('m.login.password');
|
||||
expect(req.data.identifier.type).toEqual('m.id.user');
|
||||
expect(req.data.identifier.user).toEqual('user');
|
||||
@@ -589,7 +665,8 @@ function awaitSyncingSpinner(matrixChat, retryLimit, retryCount) {
|
||||
retryCount = 0;
|
||||
}
|
||||
|
||||
if (matrixChat.state.loading || matrixChat.state.loggingIn) {
|
||||
if (matrixChat.state.view === VIEWS.LOADING ||
|
||||
matrixChat.state.view === VIEWS.LOGGING_IN) {
|
||||
console.log(Date.now() + " Awaiting sync spinner: still loading.");
|
||||
if (retryCount >= retryLimit) {
|
||||
throw new Error("MatrixChat still not loaded after " +
|
||||
@@ -628,8 +705,7 @@ function awaitRoomView(matrixChat, retryLimit, retryCount) {
|
||||
retryCount = 0;
|
||||
}
|
||||
|
||||
if (matrixChat.state.loading ||
|
||||
!(matrixChat.state.loggedIn && matrixChat.state.ready)) {
|
||||
if (matrixChat.state.view !== VIEWS.LOGGED_IN || !matrixChat.state.ready) {
|
||||
console.log(Date.now() + " Awaiting room view: not ready yet.");
|
||||
if (retryCount >= retryLimit) {
|
||||
throw new Error("MatrixChat still not ready after " +
|
||||
|
||||
@@ -34,22 +34,25 @@ export function deleteIndexedDB(dbName) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Removing indexeddb instance: ${dbName}`);
|
||||
console.log(`${Date.now()}: Removing indexeddb instance: ${dbName}`);
|
||||
const req = window.indexedDB.deleteDatabase(dbName);
|
||||
|
||||
req.onblocked = () => {
|
||||
console.log(`can't yet delete indexeddb because it is open elsewhere`);
|
||||
console.log(`${Date.now()}: can't yet delete indexeddb ${dbName} because it is open elsewhere`);
|
||||
};
|
||||
|
||||
req.onerror = (ev) => {
|
||||
reject(new Error(
|
||||
"unable to delete indexeddb: " + ev.target.error,
|
||||
`${Date.now()}: unable to delete indexeddb ${dbName}: ${ev.target.error}`,
|
||||
));
|
||||
};
|
||||
|
||||
req.onsuccess = () => {
|
||||
console.log(`Removed indexeddb instance: ${dbName}`);
|
||||
console.log(`${Date.now()}: Removed indexeddb instance: ${dbName}`);
|
||||
resolve();
|
||||
};
|
||||
}).catch((e) => {
|
||||
console.error(`${Date.now()}: Error removing indexeddb instance ${dbName}: ${e}`);
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user