Auto-detect theme
Sign with QR by default
This commit is contained in:
parent
635b2382e7
commit
b66d85ed37
@ -83,7 +83,7 @@ export default class Chat extends EventListenerBase<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setBackground(url: string): Promise<void> {
|
public setBackground(url: string): Promise<void> {
|
||||||
const theme = rootScope.settings.themes.find(t => t.name === rootScope.settings.theme);
|
const theme = rootScope.getTheme();
|
||||||
|
|
||||||
let item: HTMLElement;
|
let item: HTMLElement;
|
||||||
if(theme.background.type === 'color' && document.documentElement.style.cursor === 'grabbing') {
|
if(theme.background.type === 'color' && document.documentElement.style.cursor === 'grabbing') {
|
||||||
|
@ -101,7 +101,7 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
|
|
||||||
const themeCheckboxField = new CheckboxField({
|
const themeCheckboxField = new CheckboxField({
|
||||||
toggle: true,
|
toggle: true,
|
||||||
checked: rootScope.settings.theme === 'night'
|
checked: rootScope.getTheme().name === 'night'
|
||||||
});
|
});
|
||||||
themeCheckboxField.input.addEventListener('change', () => {
|
themeCheckboxField.input.addEventListener('change', () => {
|
||||||
rootScope.settings.theme = themeCheckboxField.input.checked ? 'night' : 'day';
|
rootScope.settings.theme = themeCheckboxField.input.checked ? 'night' : 'day';
|
||||||
@ -109,6 +109,10 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
appImManager.applyCurrentTheme();
|
appImManager.applyCurrentTheme();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
rootScope.on('theme_change', () => {
|
||||||
|
themeCheckboxField.setValueSilently(rootScope.getTheme().name === 'night');
|
||||||
|
});
|
||||||
|
|
||||||
const menuButtons: (ButtonMenuItemOptions & {verify?: () => boolean})[] = [{
|
const menuButtons: (ButtonMenuItemOptions & {verify?: () => boolean})[] = [{
|
||||||
icon: 'saved',
|
icon: 'saved',
|
||||||
text: 'SavedMessages',
|
text: 'SavedMessages',
|
||||||
|
@ -42,7 +42,7 @@ export default class AppBackgroundTab extends SliderSuperTab {
|
|||||||
this.container.classList.add('background-container', 'background-image-container');
|
this.container.classList.add('background-container', 'background-image-container');
|
||||||
this.setTitle('ChatBackground');
|
this.setTitle('ChatBackground');
|
||||||
|
|
||||||
this.theme = rootScope.settings.themes.find(t => t.name === rootScope.settings.theme);
|
this.theme = rootScope.getTheme();
|
||||||
|
|
||||||
{
|
{
|
||||||
const container = generateSection(this.scrollable);
|
const container = generateSection(this.scrollable);
|
||||||
@ -347,7 +347,7 @@ export default class AppBackgroundTab extends SliderSuperTab {
|
|||||||
|
|
||||||
private setActive = () => {
|
private setActive = () => {
|
||||||
const active = this.grid.querySelector('.active');
|
const active = this.grid.querySelector('.active');
|
||||||
const background = rootScope.settings.themes.find(t => t.name === rootScope.settings.theme).background;
|
const background = this.theme.background;
|
||||||
const target = background.type === 'image' ? this.grid.querySelector(`.grid-item[data-slug="${background.slug}"]`) : null;
|
const target = background.type === 'image' ? this.grid.querySelector(`.grid-item[data-slug="${background.slug}"]`) : null;
|
||||||
if(active === target) {
|
if(active === target) {
|
||||||
return;
|
return;
|
||||||
|
@ -5,7 +5,7 @@ import findUpClassName from "../../../helpers/dom/findUpClassName";
|
|||||||
import highlightningColor from "../../../helpers/highlightningColor";
|
import highlightningColor from "../../../helpers/highlightningColor";
|
||||||
import { throttle } from "../../../helpers/schedulers";
|
import { throttle } from "../../../helpers/schedulers";
|
||||||
import appImManager from "../../../lib/appManagers/appImManager";
|
import appImManager from "../../../lib/appManagers/appImManager";
|
||||||
import appStateManager from "../../../lib/appManagers/appStateManager";
|
import appStateManager, { Theme } from "../../../lib/appManagers/appStateManager";
|
||||||
import rootScope from "../../../lib/rootScope";
|
import rootScope from "../../../lib/rootScope";
|
||||||
import ColorPicker, { ColorPickerColor } from "../../colorPicker";
|
import ColorPicker, { ColorPickerColor } from "../../colorPicker";
|
||||||
import { SliderSuperTab } from "../../slider";
|
import { SliderSuperTab } from "../../slider";
|
||||||
@ -14,11 +14,14 @@ export default class AppBackgroundColorTab extends SliderSuperTab {
|
|||||||
private colorPicker: ColorPicker;
|
private colorPicker: ColorPicker;
|
||||||
private grid: HTMLElement;
|
private grid: HTMLElement;
|
||||||
private applyColor: (hex: string, updateColorPicker?: boolean) => void;
|
private applyColor: (hex: string, updateColorPicker?: boolean) => void;
|
||||||
|
private theme: Theme;
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.container.classList.add('background-container', 'background-color-container');
|
this.container.classList.add('background-container', 'background-color-container');
|
||||||
this.setTitle('SetColor');
|
this.setTitle('SetColor');
|
||||||
|
|
||||||
|
this.theme = rootScope.getTheme();
|
||||||
|
|
||||||
const section = new SettingSection({});
|
const section = new SettingSection({});
|
||||||
this.colorPicker = new ColorPicker();
|
this.colorPicker = new ColorPicker();
|
||||||
|
|
||||||
@ -79,7 +82,7 @@ export default class AppBackgroundColorTab extends SliderSuperTab {
|
|||||||
|
|
||||||
private setActive() {
|
private setActive() {
|
||||||
const active = this.grid.querySelector('.active');
|
const active = this.grid.querySelector('.active');
|
||||||
const background = rootScope.settings.themes.find(t => t.name === rootScope.settings.theme).background;
|
const background = this.theme.background;
|
||||||
const target = background.type === 'color' ? this.grid.querySelector(`.grid-item[data-color="${background.color}"]`) : null;
|
const target = background.type === 'color' ? this.grid.querySelector(`.grid-item[data-color="${background.color}"]`) : null;
|
||||||
if(active === target) {
|
if(active === target) {
|
||||||
return;
|
return;
|
||||||
@ -99,7 +102,7 @@ export default class AppBackgroundColorTab extends SliderSuperTab {
|
|||||||
this.colorPicker.setColor(hex);
|
this.colorPicker.setColor(hex);
|
||||||
} else {
|
} else {
|
||||||
const rgba = hexaToRgba(hex);
|
const rgba = hexaToRgba(hex);
|
||||||
const background = rootScope.settings.themes.find(t => t.name === rootScope.settings.theme).background;
|
const background = this.theme.background;
|
||||||
const hsla = highlightningColor(rgba);
|
const hsla = highlightningColor(rgba);
|
||||||
|
|
||||||
background.color = hex.toLowerCase();
|
background.color = hex.toLowerCase();
|
||||||
@ -118,7 +121,7 @@ export default class AppBackgroundColorTab extends SliderSuperTab {
|
|||||||
|
|
||||||
onOpen() {
|
onOpen() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const background = rootScope.settings.themes.find(t => t.name === rootScope.settings.theme).background;
|
const background = this.theme.background;
|
||||||
|
|
||||||
// * set active if type is color
|
// * set active if type is color
|
||||||
if(background.type === 'color') {
|
if(background.type === 'color') {
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<meta name="msapplication-TileImage" content="/assets/img/mstile-144x144.png?v=jw3mK7G9Ry">
|
<meta name="msapplication-TileImage" content="/assets/img/mstile-144x144.png?v=jw3mK7G9Ry">
|
||||||
<meta name="msapplication-config" content="/assets/img/browserconfig.xml?v=jw3mK7G9Ry">
|
<meta name="msapplication-config" content="/assets/img/browserconfig.xml?v=jw3mK7G9Ry">
|
||||||
<meta name="theme-color" content="#ffffff">
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
{{# each htmlWebpackPlugin.files.css }}
|
{{# each htmlWebpackPlugin.files.css }}
|
||||||
<link rel="stylesheet" href="{{ this }}">
|
<link rel="stylesheet" href="{{ this }}">
|
||||||
{{/ each }}
|
{{/ each }}
|
||||||
|
@ -257,6 +257,8 @@ console.timeEnd('get storage1'); */
|
|||||||
//console.log('got auth:', auth);
|
//console.log('got auth:', auth);
|
||||||
//console.timeEnd('get storage');
|
//console.timeEnd('get storage');
|
||||||
|
|
||||||
|
rootScope.default.setThemeListener();
|
||||||
|
|
||||||
if(langPack.appVersion !== App.langPackVersion) {
|
if(langPack.appVersion !== App.langPackVersion) {
|
||||||
I18n.default.getLangPack(langPack.lang_code);
|
I18n.default.getLangPack(langPack.lang_code);
|
||||||
}
|
}
|
||||||
@ -286,6 +288,9 @@ console.timeEnd('get storage1'); */
|
|||||||
case 'authStateSignIn':
|
case 'authStateSignIn':
|
||||||
(await import('./pages/pageSignIn')).default.mount();
|
(await import('./pages/pageSignIn')).default.mount();
|
||||||
break;
|
break;
|
||||||
|
case 'authStateSignQr':
|
||||||
|
(await import('./pages/pageSignQR')).default.mount();
|
||||||
|
break;
|
||||||
case 'authStateAuthCode':
|
case 'authStateAuthCode':
|
||||||
(await import('./pages/pageAuthCode')).default.mount(authState.sentCode);
|
(await import('./pages/pageAuthCode')).default.mount(authState.sentCode);
|
||||||
break;
|
break;
|
||||||
|
@ -38,7 +38,7 @@ import appDraftsManager from './appDraftsManager';
|
|||||||
import serverTimeManager from '../mtproto/serverTimeManager';
|
import serverTimeManager from '../mtproto/serverTimeManager';
|
||||||
import sessionStorage from '../sessionStorage';
|
import sessionStorage from '../sessionStorage';
|
||||||
import appDownloadManager from './appDownloadManager';
|
import appDownloadManager from './appDownloadManager';
|
||||||
import appStateManager, { AppStateManager } from './appStateManager';
|
import { AppStateManager } from './appStateManager';
|
||||||
import { MOUNT_CLASS_TO } from '../../config/debug';
|
import { MOUNT_CLASS_TO } from '../../config/debug';
|
||||||
import appNavigationController from '../../components/appNavigationController';
|
import appNavigationController from '../../components/appNavigationController';
|
||||||
import appNotificationsManager from './appNotificationsManager';
|
import appNotificationsManager from './appNotificationsManager';
|
||||||
@ -170,6 +170,10 @@ export class AppImManager {
|
|||||||
this.saveChatPosition(chat);
|
this.saveChatPosition(chat);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
rootScope.on('theme_change', () => {
|
||||||
|
this.applyCurrentTheme();
|
||||||
|
});
|
||||||
|
|
||||||
sessionStorage.get('chatPositions').then((c) => {
|
sessionStorage.get('chatPositions').then((c) => {
|
||||||
sessionStorage.setToCache('chatPositions', c || {});
|
sessionStorage.setToCache('chatPositions', c || {});
|
||||||
});
|
});
|
||||||
@ -247,7 +251,7 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setCurrentBackground(broadcastEvent = false) {
|
public setCurrentBackground(broadcastEvent = false) {
|
||||||
const theme = rootScope.settings.themes.find(t => t.name === rootScope.settings.theme);
|
const theme = rootScope.getTheme();
|
||||||
|
|
||||||
if(theme.background.type === 'image' || (theme.background.type === 'default' && theme.background.slug)) {
|
if(theme.background.type === 'image' || (theme.background.type === 'default' && theme.background.slug)) {
|
||||||
const defaultTheme = AppStateManager.STATE_INIT.settings.themes.find(t => t.name === theme.name);
|
const defaultTheme = AppStateManager.STATE_INIT.settings.themes.find(t => t.name === theme.name);
|
||||||
@ -327,7 +331,7 @@ export class AppImManager {
|
|||||||
|
|
||||||
public applyHighlightningColor() {
|
public applyHighlightningColor() {
|
||||||
let hsla: string;
|
let hsla: string;
|
||||||
const theme = rootScope.settings.themes.find(t => t.name === rootScope.settings.theme);
|
const theme = rootScope.getTheme();
|
||||||
if(theme.background.highlightningColor) {
|
if(theme.background.highlightningColor) {
|
||||||
hsla = theme.background.highlightningColor;
|
hsla = theme.background.highlightningColor;
|
||||||
document.documentElement.style.setProperty('--message-highlightning-color', hsla);
|
document.documentElement.style.setProperty('--message-highlightning-color', hsla);
|
||||||
@ -352,7 +356,7 @@ export class AppImManager {
|
|||||||
public applyCurrentTheme(slug?: string, backgroundUrl?: string, broadcastEvent?: boolean) {
|
public applyCurrentTheme(slug?: string, backgroundUrl?: string, broadcastEvent?: boolean) {
|
||||||
this.applyHighlightningColor();
|
this.applyHighlightningColor();
|
||||||
|
|
||||||
document.documentElement.classList.toggle('night', rootScope.settings.theme === 'night');
|
rootScope.setTheme();
|
||||||
|
|
||||||
if(backgroundUrl) {
|
if(backgroundUrl) {
|
||||||
this.backgroundPromises[slug] = Promise.resolve(backgroundUrl);
|
this.backgroundPromises[slug] = Promise.resolve(backgroundUrl);
|
||||||
|
@ -4222,7 +4222,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private setDialogToStateIfMessageIsTop(message: any) {
|
public setDialogToStateIfMessageIsTop(message: any) {
|
||||||
const dialog = this.getDialogOnly(message.peerId);
|
const dialog = this.getDialogOnly(message.peerId);
|
||||||
if(dialog && dialog.top_message === message.mid) {
|
if(dialog && dialog.top_message === message.mid) {
|
||||||
this.dialogsStorage.setDialogToState(dialog);
|
this.dialogsStorage.setDialogToState(dialog);
|
||||||
|
@ -32,7 +32,7 @@ export type Background = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type Theme = {
|
export type Theme = {
|
||||||
name: 'day' | 'night',
|
name: 'day' | 'night' | 'system',
|
||||||
background: Background
|
background: Background
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ export const STATE_INIT: State = {
|
|||||||
recentSearch: [],
|
recentSearch: [],
|
||||||
version: STATE_VERSION,
|
version: STATE_VERSION,
|
||||||
authState: {
|
authState: {
|
||||||
_: 'authStateSignIn'
|
_: 'authStateSignQr'
|
||||||
},
|
},
|
||||||
hiddenPinnedMessages: {},
|
hiddenPinnedMessages: {},
|
||||||
settings: {
|
settings: {
|
||||||
@ -134,7 +134,7 @@ export const STATE_INIT: State = {
|
|||||||
highlightningColor: 'hsla(0, 0%, 3.82353%, 0.4)'
|
highlightningColor: 'hsla(0, 0%, 3.82353%, 0.4)'
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
theme: 'day',
|
theme: 'system',
|
||||||
notifications: {
|
notifications: {
|
||||||
sound: false
|
sound: false
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import type { ConnectionStatusChange } from "../types";
|
|||||||
import type { UserTyping } from "./appManagers/appChatsManager";
|
import type { UserTyping } from "./appManagers/appChatsManager";
|
||||||
import type Chat from "../components/chat/chat";
|
import type Chat from "../components/chat/chat";
|
||||||
import type { UserAuth } from "./mtproto/mtproto_config";
|
import type { UserAuth } from "./mtproto/mtproto_config";
|
||||||
import type { State } from "./appManagers/appStateManager";
|
import type { State, Theme } from "./appManagers/appStateManager";
|
||||||
import type { MyDraftMessage } from "./appManagers/appDraftsManager";
|
import type { MyDraftMessage } from "./appManagers/appDraftsManager";
|
||||||
import EventListenerBase from "../helpers/eventListenerBase";
|
import EventListenerBase from "../helpers/eventListenerBase";
|
||||||
import { MOUNT_CLASS_TO } from "../config/debug";
|
import { MOUNT_CLASS_TO } from "../config/debug";
|
||||||
@ -109,6 +109,8 @@ export type BroadcastEvents = {
|
|||||||
'notify_peer_type_settings': {key: Exclude<NotifyPeer['_'], 'notifyPeer'>, settings: PeerNotifySettings},
|
'notify_peer_type_settings': {key: Exclude<NotifyPeer['_'], 'notifyPeer'>, settings: PeerNotifySettings},
|
||||||
|
|
||||||
'language_change': void,
|
'language_change': void,
|
||||||
|
|
||||||
|
'theme_change': void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class RootScope extends EventListenerBase<{
|
export class RootScope extends EventListenerBase<{
|
||||||
@ -124,6 +126,7 @@ export class RootScope extends EventListenerBase<{
|
|||||||
public connectionStatus: {[name: string]: ConnectionStatusChange} = {};
|
public connectionStatus: {[name: string]: ConnectionStatusChange} = {};
|
||||||
public settings: State['settings'];
|
public settings: State['settings'];
|
||||||
public peerId = 0;
|
public peerId = 0;
|
||||||
|
public systemTheme: Theme['name'];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -142,6 +145,27 @@ export class RootScope extends EventListenerBase<{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setThemeListener() {
|
||||||
|
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
const checkDarkMode = () => {
|
||||||
|
//const theme = this.getTheme();
|
||||||
|
this.systemTheme = darkModeMediaQuery.matches ? 'night' : 'day';
|
||||||
|
//const newTheme = this.getTheme();
|
||||||
|
|
||||||
|
if(this.myId) {
|
||||||
|
this.broadcast('theme_change');
|
||||||
|
} else {
|
||||||
|
this.setTheme();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
darkModeMediaQuery.addEventListener('change', checkDarkMode);
|
||||||
|
checkDarkMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setTheme() {
|
||||||
|
document.documentElement.classList.toggle('night', this.getTheme().name === 'night');
|
||||||
|
}
|
||||||
|
|
||||||
get overlayIsActive() {
|
get overlayIsActive() {
|
||||||
return this._overlayIsActive;
|
return this._overlayIsActive;
|
||||||
}
|
}
|
||||||
@ -151,6 +175,10 @@ export class RootScope extends EventListenerBase<{
|
|||||||
this.broadcast('overlay_toggle', value);
|
this.broadcast('overlay_toggle', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getTheme(name: Theme['name'] = this.settings.theme === 'system' ? this.systemTheme : this.settings.theme) {
|
||||||
|
return this.settings.themes.find(t => t.name === name);
|
||||||
|
}
|
||||||
|
|
||||||
public broadcast = <T extends keyof BroadcastEvents>(name: T, detail?: BroadcastEvents[T]) => {
|
public broadcast = <T extends keyof BroadcastEvents>(name: T, detail?: BroadcastEvents[T]) => {
|
||||||
/* //if(DEBUG) {
|
/* //if(DEBUG) {
|
||||||
if(name !== 'user_update') {
|
if(name !== 'user_update') {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
//import apiManager from '../lib/mtproto/apiManager';
|
|
||||||
/*
|
/*
|
||||||
* https://github.com/morethanwords/tweb
|
* https://github.com/morethanwords/tweb
|
||||||
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||||
@ -17,11 +16,16 @@ import { pause } from '../helpers/schedulers';
|
|||||||
import App from '../config/app';
|
import App from '../config/app';
|
||||||
import Button from '../components/button';
|
import Button from '../components/button';
|
||||||
import { _i18n, i18n, LangPackKey } from '../lib/langPack';
|
import { _i18n, i18n, LangPackKey } from '../lib/langPack';
|
||||||
|
import appStateManager from '../lib/appManagers/appStateManager';
|
||||||
|
import rootScope from '../lib/rootScope';
|
||||||
|
import { putPreloader } from '../components/misc';
|
||||||
|
|
||||||
let onFirstMount = async() => {
|
let onFirstMount = async() => {
|
||||||
const pageElement = page.pageEl;
|
const pageElement = page.pageEl;
|
||||||
const imageDiv = pageElement.querySelector('.auth-image') as HTMLDivElement;
|
const imageDiv = pageElement.querySelector('.auth-image') as HTMLDivElement;
|
||||||
|
|
||||||
|
let preloader = putPreloader(imageDiv, true);
|
||||||
|
|
||||||
const inputWrapper = document.createElement('div');
|
const inputWrapper = document.createElement('div');
|
||||||
inputWrapper.classList.add('input-wrapper');
|
inputWrapper.classList.add('input-wrapper');
|
||||||
|
|
||||||
@ -54,10 +58,10 @@ let onFirstMount = async() => {
|
|||||||
const QRCodeStyling = results[0].default;
|
const QRCodeStyling = results[0].default;
|
||||||
|
|
||||||
let stop = false;
|
let stop = false;
|
||||||
document.addEventListener('user_auth', () => {
|
rootScope.addEventListener('user_auth', () => {
|
||||||
stop = true;
|
stop = true;
|
||||||
cachedPromise = null;
|
cachedPromise = null;
|
||||||
}, {once: true});
|
}, true);
|
||||||
|
|
||||||
let options: {dcId?: number, ignoreErrors: true} = {ignoreErrors: true};
|
let options: {dcId?: number, ignoreErrors: true} = {ignoreErrors: true};
|
||||||
let prevToken: Uint8Array | number[];
|
let prevToken: Uint8Array | number[];
|
||||||
@ -99,20 +103,46 @@ let onFirstMount = async() => {
|
|||||||
let encoded = bytesToBase64(loginToken.token);
|
let encoded = bytesToBase64(loginToken.token);
|
||||||
let url = "tg://login?token=" + encoded.replace(/\+/g, "-").replace(/\//g, "_").replace(/\=+$/, "");
|
let url = "tg://login?token=" + encoded.replace(/\+/g, "-").replace(/\//g, "_").replace(/\=+$/, "");
|
||||||
|
|
||||||
|
const style = window.getComputedStyle(document.documentElement);
|
||||||
|
const surfaceColor = style.getPropertyValue('--surface-color').trim();
|
||||||
|
const textColor = style.getPropertyValue('--primary-text-color').trim();
|
||||||
|
const primaryColor = style.getPropertyValue('--primary-color').trim();
|
||||||
|
|
||||||
|
const logoUrl = await fetch('assets/img/logo_padded.svg')
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(text => {
|
||||||
|
text = text.replace(/(fill:).+?(;)/, `$1${primaryColor}$2`);
|
||||||
|
const blob = new Blob([text], {type: 'image/svg+xml;charset=utf-8'});
|
||||||
|
|
||||||
|
// * because iOS Safari doesn't want to eat objectURL
|
||||||
|
return new Promise<string>((resolve) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
resolve(e.target.result as string);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
});
|
||||||
|
//return URL.createObjectURL(blob);
|
||||||
|
});
|
||||||
|
|
||||||
const qrCode = new QRCodeStyling({
|
const qrCode = new QRCodeStyling({
|
||||||
width: 240 * window.devicePixelRatio,
|
width: 240 * window.devicePixelRatio,
|
||||||
height: 240 * window.devicePixelRatio,
|
height: 240 * window.devicePixelRatio,
|
||||||
data: url,
|
data: url,
|
||||||
image: "assets/img/logo_padded.svg",
|
image: logoUrl,
|
||||||
dotsOptions: {
|
dotsOptions: {
|
||||||
color: "#000000",
|
color: textColor,
|
||||||
type: "rounded"
|
type: 'rounded'
|
||||||
|
},
|
||||||
|
cornersSquareOptions: {
|
||||||
|
type: 'extra-rounded'
|
||||||
},
|
},
|
||||||
imageOptions: {
|
imageOptions: {
|
||||||
imageSize: .75
|
imageSize: 1,
|
||||||
|
margin: 0
|
||||||
},
|
},
|
||||||
backgroundOptions: {
|
backgroundOptions: {
|
||||||
color: "#ffffff"
|
color: surfaceColor
|
||||||
},
|
},
|
||||||
qrOptions: {
|
qrOptions: {
|
||||||
errorCorrectionLevel: "L"
|
errorCorrectionLevel: "L"
|
||||||
@ -138,9 +168,25 @@ let onFirstMount = async() => {
|
|||||||
|
|
||||||
// * это костыль, но библиотека не предоставляет никаких событий
|
// * это костыль, но библиотека не предоставляет никаких событий
|
||||||
await promise.then(() => {
|
await promise.then(() => {
|
||||||
Array.from(imageDiv.children).slice(0, -1).forEach(el => {
|
if(preloader) {
|
||||||
el.remove();
|
preloader.style.animation = 'hide-icon .4s forwards';
|
||||||
});
|
|
||||||
|
const c = imageDiv.children[1] as HTMLElement;
|
||||||
|
c.style.display = 'none';
|
||||||
|
c.style.animation = 'grow-icon .4s forwards';
|
||||||
|
setTimeout(() => {
|
||||||
|
c.style.display = '';
|
||||||
|
}, 150);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
c.style.animation = '';
|
||||||
|
}, 500);
|
||||||
|
preloader = undefined;
|
||||||
|
} else {
|
||||||
|
Array.from(imageDiv.children).slice(0, -1).forEach(el => {
|
||||||
|
el.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +217,7 @@ let onFirstMount = async() => {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
await iterate(false);
|
//await iterate(false);
|
||||||
|
|
||||||
return async() => {
|
return async() => {
|
||||||
stop = false;
|
stop = false;
|
||||||
@ -198,6 +244,8 @@ const page = new Page('page-signQR', true, () => {
|
|||||||
cachedPromise.then(func => {
|
cachedPromise.then(func => {
|
||||||
func();
|
func();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
appStateManager.pushToState('authState', {_: 'authStateSignQr'});
|
||||||
});
|
});
|
||||||
|
|
||||||
export default page;
|
export default page;
|
||||||
|
@ -117,6 +117,7 @@
|
|||||||
&:-webkit-autofill:active {
|
&:-webkit-autofill:active {
|
||||||
font-family: "Roboto", -apple-system, apple color emoji, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
|
font-family: "Roboto", -apple-system, apple color emoji, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
|
||||||
font-size: 1rem !important;
|
font-size: 1rem !important;
|
||||||
|
color: var(--primary-text-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
@ -428,7 +429,7 @@ input:focus, button:focus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include hover() {
|
@include hover() {
|
||||||
color: #000;
|
color: var(--primary-text-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#auth-pages {
|
#auth-pages {
|
||||||
max-width: 720px; // 360 + 360 / 2
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
background: var(--surface-color);
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@ -42,6 +43,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
max-width: 720px; // 360 + 360 / 2
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
.auth-placeholder {
|
.auth-placeholder {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -73,7 +76,7 @@
|
|||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: #fff;
|
background: var(--surface-color);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,14 +170,29 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.page-signQR {
|
.page-signQR {
|
||||||
|
overflow: unset !important;
|
||||||
|
|
||||||
.auth-image {
|
.auth-image {
|
||||||
width: 240px !important;
|
width: 240px !important;
|
||||||
height: 240px !important;
|
height: 240px !important;
|
||||||
overflow: hidden;
|
//overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.preloader {
|
||||||
|
transform: none;
|
||||||
|
left: unset;
|
||||||
|
top: unset;
|
||||||
|
}
|
||||||
|
|
||||||
.qr-canvas {
|
.qr-canvas {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
& + .qr-canvas {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +219,14 @@ html.night {
|
|||||||
// * Night theme end
|
// * Night theme end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@import "partials/ico";
|
@import "partials/ico";
|
||||||
@import "partials/input";
|
@import "partials/input";
|
||||||
@import "partials/button";
|
@import "partials/button";
|
||||||
@ -671,7 +679,7 @@ hr {
|
|||||||
top: calc(100% + .5rem);
|
top: calc(100% + .5rem);
|
||||||
left: 0;
|
left: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
background-color: var(--surface-color);
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
border-radius: $border-radius-medium;
|
border-radius: $border-radius-medium;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
6
src/types.d.ts
vendored
6
src/types.d.ts
vendored
@ -42,12 +42,16 @@ export type AnyFunction = (...args: any) => any;
|
|||||||
export type AnyToVoidFunction = (...args: any) => void;
|
export type AnyToVoidFunction = (...args: any) => void;
|
||||||
export type NoneToVoidFunction = () => void;
|
export type NoneToVoidFunction = () => void;
|
||||||
|
|
||||||
export type AuthState = AuthState.signIn | AuthState.authCode | AuthState.password | AuthState.signUp | AuthState.signedIn;
|
export type AuthState = AuthState.signIn | AuthState.signQr | AuthState.authCode | AuthState.password | AuthState.signUp | AuthState.signedIn;
|
||||||
export namespace AuthState {
|
export namespace AuthState {
|
||||||
export type signIn = {
|
export type signIn = {
|
||||||
_: 'authStateSignIn'
|
_: 'authStateSignIn'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type signQr = {
|
||||||
|
_: 'authStateSignQr'
|
||||||
|
};
|
||||||
|
|
||||||
export type authCode = {
|
export type authCode = {
|
||||||
_: 'authStateAuthCode',
|
_: 'authStateAuthCode',
|
||||||
sentCode: AuthSentCode.authSentCode
|
sentCode: AuthSentCode.authSentCode
|
||||||
|
Loading…
x
Reference in New Issue
Block a user