Browse Source

Layout changes:

Input new hover
Checkbox ripple
Row click
master
Eduard Kuzmenko 3 years ago
parent
commit
2a6e7d1178
  1. 9
      src/components/checkboxField.ts
  2. 4
      src/components/ripple.ts
  3. 31
      src/components/row.ts
  4. 3
      src/components/sidebarLeft/tabs/background.ts
  5. 19
      src/components/sidebarLeft/tabs/editProfile.ts
  6. 27
      src/components/sidebarLeft/tabs/generalSettings.ts
  7. 1
      src/components/sidebarLeft/tabs/settings.ts
  8. 10
      src/lib/mtproto/mtprotoworker.ts
  9. 4
      src/scss/components/_global.scss
  10. 5
      src/scss/partials/_checkbox.scss
  11. 27
      src/scss/partials/_input.scss
  12. 27
      src/scss/partials/_leftSidebar.scss
  13. 13
      src/scss/style.scss

9
src/components/checkboxField.ts

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
import appStateManager from "../lib/appManagers/appStateManager";
import { getDeepProperty } from "../helpers/object";
import { ripple } from "./ripple";
export default class CheckboxField {
public input: HTMLInputElement;
@ -13,7 +14,8 @@ export default class CheckboxField { @@ -13,7 +14,8 @@ export default class CheckboxField {
stateKey?: string,
disabled?: boolean,
checked?: boolean,
restriction?: boolean
restriction?: boolean,
withRipple?: boolean
} = {}) {
const label = this.label = document.createElement('label');
label.classList.add('checkbox-field');
@ -86,6 +88,11 @@ export default class CheckboxField { @@ -86,6 +88,11 @@ export default class CheckboxField {
if(span) {
label.append(span);
}
if(options.withRipple) {
label.classList.add('checkbox-ripple', 'hover-effect');
ripple(label, undefined, undefined, true);
}
}
get checked() {

4
src/components/ripple.ts

@ -3,7 +3,7 @@ import { findUpClassName } from "../helpers/dom"; @@ -3,7 +3,7 @@ import { findUpClassName } from "../helpers/dom";
import rootScope from "../lib/rootScope";
let rippleClickId = 0;
export function ripple(elem: HTMLElement, callback: (id: number) => Promise<boolean | void> = () => Promise.resolve(), onEnd: (id: number) => void = null) {
export function ripple(elem: HTMLElement, callback: (id: number) => Promise<boolean | void> = () => Promise.resolve(), onEnd: (id: number) => void = null, prepend = false) {
//return;
if(elem.querySelector('.c-ripple')) return;
elem.classList.add('rp');
@ -16,7 +16,7 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool @@ -16,7 +16,7 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool
r.classList.add('is-square');
}
elem.append(r);
elem[prepend ? 'prepend' : 'append'](r);
let handler: () => void;
//let animationEndPromise: Promise<number>;

31
src/components/row.ts

@ -3,6 +3,7 @@ import RadioField from "./radioField"; @@ -3,6 +3,7 @@ import RadioField from "./radioField";
import { ripple } from "./ripple";
import { SliderSuperTab } from "./slider";
import RadioForm from "./radioForm";
import { attachClickEvent, cancelEvent } from "../helpers/dom";
export default class Row {
public container: HTMLElement;
@ -19,6 +20,7 @@ export default class Row { @@ -19,6 +20,7 @@ export default class Row {
subtitle: string,
radioField: Row['radioField'],
checkboxField: Row['checkboxField'],
noCheckboxSubtitle: boolean,
title: string,
titleRight: string,
clickable: boolean | ((e: Event) => void),
@ -45,8 +47,25 @@ export default class Row { @@ -45,8 +47,25 @@ export default class Row {
this.checkboxField = options.checkboxField;
this.container.append(this.checkboxField.label);
this.checkboxField.input.addEventListener('change', () => {
this.subtitle.innerHTML = this.checkboxField.input.checked ? 'Enabled' : 'Disabled';
if(!options.noCheckboxSubtitle) {
this.checkboxField.input.addEventListener('change', () => {
this.subtitle.innerHTML = this.checkboxField.input.checked ? 'Enabled' : 'Disabled';
});
}
}
const i = options.radioField || options.checkboxField;
i.label.classList.add('disable-hover');
if(options.radioField) {
attachClickEvent(this.container, (e) => {
cancelEvent(e);
i.checked = true;
});
} else {
attachClickEvent(this.container, (e) => {
cancelEvent(e);
i.checked = !i.checked;
});
}
} else {
@ -88,7 +107,7 @@ export default class Row { @@ -88,7 +107,7 @@ export default class Row {
options.clickable = () => options.navigationTab.open();
}
if(options.clickable) {
if(options.clickable || options.radioField || options.checkboxField) {
if(typeof(options.clickable) === 'function') {
this.container.addEventListener('click', (e) => {
if(this.freezed) return;
@ -97,7 +116,11 @@ export default class Row { @@ -97,7 +116,11 @@ export default class Row {
}
this.container.classList.add('row-clickable', 'hover-effect');
ripple(this.container);
ripple(this.container, undefined, undefined, true);
/* if(options.radioField || options.checkboxField) {
this.container.prepend(this.container.lastElementChild);
} */
}
this.container.append(this.subtitle);

3
src/components/sidebarLeft/tabs/background.ts

@ -31,7 +31,8 @@ export default class AppBackgroundTab extends SliderSuperTab { @@ -31,7 +31,8 @@ export default class AppBackgroundTab extends SliderSuperTab {
const blurCheckboxField = new CheckboxField({
text: 'Blur Wallpaper Image',
name: 'blur',
stateKey: 'settings.background.blur'
stateKey: 'settings.background.blur',
withRipple: true
});
blurCheckboxField.input.addEventListener('change', () => {
const active = grid.querySelector('.active') as HTMLElement;

19
src/components/sidebarLeft/tabs/editProfile.ts

@ -19,7 +19,7 @@ export default class AppEditProfileTab extends SliderSuperTab { @@ -19,7 +19,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
private editPeer: EditPeer;
protected init() {
protected async init() {
this.container.classList.add('edit-profile-container');
this.title.innerText = 'Edit Profile';
@ -127,27 +127,16 @@ export default class AppEditProfileTab extends SliderSuperTab { @@ -127,27 +127,16 @@ export default class AppEditProfileTab extends SliderSuperTab {
this.editPeer.nextBtn.removeAttribute('disabled');
});
}, {listenerSetter: this.listenerSetter});
}
public fillElements() {
if(this.init) {
this.init();
this.init = null;
}
const user = appUsersManager.getSelf();
const userFull = await appProfileManager.getProfile(user.id, true);
this.firstNameInputField.setOriginalValue(user.first_name, true);
this.lastNameInputField.setOriginalValue(user.last_name, true);
this.bioInputField.setOriginalValue('', true);
this.bioInputField.setOriginalValue(userFull.about, true);
this.usernameInputField.setOriginalValue(user.username, true);
appProfileManager.getProfile(user.id, true).then(userFull => {
if(userFull.about) {
this.bioInputField.setOriginalValue(userFull.about);
}
});
this.setProfileUrl();
this.editPeer.handleChange();
}

27
src/components/sidebarLeft/tabs/generalSettings.ts

@ -76,7 +76,8 @@ export default class AppGeneralSettingsTab extends SliderSuperTab { @@ -76,7 +76,8 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
const animationsCheckboxField = new CheckboxField({
text: 'Enable Animations',
name: 'animations',
stateKey: 'settings.animationsEnabled'
stateKey: 'settings.animationsEnabled',
withRipple: true
});
container.append(range.container, chatBackgroundButton, animationsCheckboxField.label);
@ -118,22 +119,26 @@ export default class AppGeneralSettingsTab extends SliderSuperTab { @@ -118,22 +119,26 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
const contactsCheckboxField = new CheckboxField({
text: 'Contacts',
name: 'contacts',
stateKey: 'settings.autoDownload.contacts'
stateKey: 'settings.autoDownload.contacts',
withRipple: true
});
const privateCheckboxField = new CheckboxField({
text: 'Private Chats',
name: 'private',
stateKey: 'settings.autoDownload.private'
stateKey: 'settings.autoDownload.private',
withRipple: true
});
const groupsCheckboxField = new CheckboxField({
text: 'Group Chats',
name: 'groups',
stateKey: 'settings.autoDownload.groups'
stateKey: 'settings.autoDownload.groups',
withRipple: true
});
const channelsCheckboxField = new CheckboxField({
text: 'Channels',
name: 'channels',
stateKey: 'settings.autoDownload.channels'
stateKey: 'settings.autoDownload.channels',
withRipple: true
});
container.append(contactsCheckboxField.label, privateCheckboxField.label, groupsCheckboxField.label, channelsCheckboxField.label);
@ -146,12 +151,14 @@ export default class AppGeneralSettingsTab extends SliderSuperTab { @@ -146,12 +151,14 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
const gifsCheckboxField = new CheckboxField({
text: 'GIFs',
name: 'gifs',
stateKey: 'settings.autoPlay.gifs'
stateKey: 'settings.autoPlay.gifs',
withRipple: true
});
const videosCheckboxField = new CheckboxField({
text: 'Videos',
name: 'videos',
stateKey: 'settings.autoPlay.videos'
stateKey: 'settings.autoPlay.videos',
withRipple: true
});
container.append(gifsCheckboxField.label, videosCheckboxField.label);
@ -163,12 +170,14 @@ export default class AppGeneralSettingsTab extends SliderSuperTab { @@ -163,12 +170,14 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
const suggestCheckboxField = new CheckboxField({
text: 'Suggest Stickers by Emoji',
name: 'suggest',
stateKey: 'settings.stickers.suggest'
stateKey: 'settings.stickers.suggest',
withRipple: true
});
const loopCheckboxField = new CheckboxField({
text: 'Loop Animated Stickers',
name: 'loop',
stateKey: 'settings.stickers.loop'
stateKey: 'settings.stickers.loop',
withRipple: true
});
container.append(suggestCheckboxField.label, loopCheckboxField.label);

1
src/components/sidebarLeft/tabs/settings.ts

@ -112,7 +112,6 @@ export default class AppSettingsTab extends SliderSuperTab { @@ -112,7 +112,6 @@ export default class AppSettingsTab extends SliderSuperTab {
this.buttons.edit.addEventListener('click', () => {
const tab = new AppEditProfileTab(this.slider);
tab.fillElements();
tab.open();
});

10
src/lib/mtproto/mtprotoworker.ts

@ -55,7 +55,7 @@ export class ApiManagerProxy extends CryptoWorkerMethods { @@ -55,7 +55,7 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
private isSWRegistered = true;
private debug = DEBUG && false;
private debug = DEBUG /* && false */;
private sockets: Map<number, Socket> = new Map();
@ -319,7 +319,7 @@ export class ApiManagerProxy extends CryptoWorkerMethods { @@ -319,7 +319,7 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
(options as MTMessage).messageId = o.prepareTempMessageId;
//console.log('will invokeApi:', method, params, options);
return this.performTaskWorker('invokeApi', method, params, o);
return this.invokeApi(method, params, o);
}
public invokeApiHashable<T extends keyof MethodDeclMap>(method: T, params: Omit<MethodDeclMap[T]['req'], 'hash'> = {} as any, options: InvokeApiOptions = {}): Promise<MethodDeclMap[T]['res']> {
@ -334,7 +334,7 @@ export class ApiManagerProxy extends CryptoWorkerMethods { @@ -334,7 +334,7 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
}
}
return this.performTaskWorker('invokeApi', method, params, options).then((result: any) => {
return this.invokeApi(method, params, options).then((result: any) => {
if(result._.includes('NotModified')) {
this.debug && this.log.warn('NotModified saved!', method, queryJSON);
return cached.result;
@ -355,7 +355,9 @@ export class ApiManagerProxy extends CryptoWorkerMethods { @@ -355,7 +355,9 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
}
/* private computeHash(smth: any[]) {
return smth.reduce((hash, v) => (((hash * 0x4F25) & 0x7FFFFFFF) + v.id) & 0x7FFFFFFF, 0);
smth = smth.slice().sort((a, b) => a.id - b.id);
//return smth.reduce((hash, v) => (((hash * 0x4F25) & 0x7FFFFFFF) + v.id) & 0x7FFFFFFF, 0);
return smth.reduce((hash, v) => ((hash * 20261) + 0x80000000 + v.id) % 0x80000000, 0);
} */
public setBaseDcId(dcId: number) {

4
src/scss/components/_global.scss

@ -86,6 +86,10 @@ Utility Classes @@ -86,6 +86,10 @@ Utility Classes
display: none !important;
}
.hide-overflow {
overflow: hidden;
}
// No Text Select
.no-select/* , .no-select * */ {
user-select: none;

5
src/scss/partials/_checkbox.scss

@ -92,6 +92,11 @@ @@ -92,6 +92,11 @@
}
}
.checkbox-ripple {
overflow: hidden;
border-radius: $border-radius-medium;
}
.checkbox-field-round {
--size: 1.5rem;

27
src/scss/partials/_input.scss

@ -70,7 +70,7 @@ @@ -70,7 +70,7 @@
box-sizing: border-box;
width: 100%;
min-height: var(--height);
transition: .2s border-color;
transition: 0s border-color;
position: relative;
z-index: 1;
line-height: 1.3125;
@ -86,10 +86,16 @@ @@ -86,10 +86,16 @@
transition: none;
}
html.no-touch & {
&:hover:not(:focus):not(.error):not(.valid) {
border-color: var(--color-gray);
@include hover() {
&:not(:focus):not(.error):not(.valid) {
//border-color: var(--color-gray);
border-color: #000;
transition: .2s border-color;
}
/* &:not(:focus):not(.error):not(.valid) ~ label {
transition: .2s transform, .2s padding, .1s opacity, font-weight 0s 1s;
} */
}
/* font-weight: 500; */
@ -140,6 +146,12 @@ @@ -140,6 +146,12 @@
color: $button-primary-background;
font-weight: 500;
}
// * valid for plain text, empty for contenteditable
&:valid ~ label,
&:not(:empty):focus ~ label {
transition-delay: 0s, 0s, 0s, 0s;
}
&:focus ~ label,
&:valid ~ label,
@ -251,8 +263,11 @@ input:focus, button:focus { @@ -251,8 +263,11 @@ input:focus, button:focus {
transition: none;
}
&:hover {
border-color: var(--color-gray);
@include hover() {
&:not(:focus) {
border-color: var(--color-gray) !important;
//border-color: #000;
}
}
&:focus {

27
src/scss/partials/_leftSidebar.scss

@ -501,10 +501,10 @@ @@ -501,10 +501,10 @@
.edit-profile-container {
.caption {
margin-top: 1.063rem;
margin-left: 1.438rem;
line-height: 1.2;
padding-bottom: 1.438rem;
margin-top: 1.0625rem;
margin-left: 1.4375rem;
line-height: var(--line-height);
padding-bottom: 1.4375rem;
@include respond-to(handhelds) {
padding-right: 24px;
@ -512,7 +512,7 @@ @@ -512,7 +512,7 @@
}
.sidebar-left-h2 {
padding: 0 1.438rem;
padding: 0 1.4375rem;
padding-bottom: 1.5rem;
}
@ -540,7 +540,7 @@ @@ -540,7 +540,7 @@
text-align: center;
color: #707579;
font-size: 14px;
line-height: 1.3;
line-height: var(--line-height);
}
}
@ -836,6 +836,12 @@ @@ -836,6 +836,12 @@
> .btn-primary {
margin: 0;
}
> .checkbox-field {
.checkbox-box {
left: auto;
}
}
}
&-name {
@ -851,7 +857,7 @@ @@ -851,7 +857,7 @@
margin-top: 1rem;
font-size: 1rem;
color: #707579;
line-height: 1.3125;
line-height: var(--line-height);
padding: 0 1rem;
@include respond-to(handhelds) {
@ -872,8 +878,7 @@ @@ -872,8 +878,7 @@
display: flex;
align-items: center;
height: 3.5rem;
margin: 0 1.0625rem;
padding: 0;
padding: 0 1.1875rem;
}
&-disabled {
@ -1032,6 +1037,10 @@ @@ -1032,6 +1037,10 @@
.sidebar-left-section:first-child {
padding-bottom: 0;
.row-title {
font-weight: 500;
}
}
}

13
src/scss/style.scss

@ -62,6 +62,7 @@ $chat-padding-handhelds: .5rem; @@ -62,6 +62,7 @@ $chat-padding-handhelds: .5rem;
--messages-container-width: #{$messages-container-width};
--messages-text-size: 16px;
--messages-secondary-text-size: calc(var(--messages-text-size) - 1px);
--line-height: 1.3125;
--esg-sticker-size: 80px;
// https://github.com/overtake/TelegramSwift/blob/5cc7d2475fe4738a6aa0486c23eaf80a89d33b97/submodules/TGUIKit/TGUIKit/PresentationTheme.swift#L2054
@ -1111,7 +1112,7 @@ middle-ellipsis-element { @@ -1111,7 +1112,7 @@ middle-ellipsis-element {
}
&-title {
line-height: 1.3125;
line-height: var(--line-height);
&-right {
flex: 0 0 auto !important;
@ -1157,11 +1158,13 @@ middle-ellipsis-element { @@ -1157,11 +1158,13 @@ middle-ellipsis-element {
&-subtitle {
color: var(--color-text-secondary) !important;
font-size: .875rem !important;
line-height: var(--line-height);
margin-top: .125rem;
margin-bottom: .0625rem;
// * lol
line-height: 1rem;
margin-top: .1875rem;
margin-bottom: .125rem;
&:empty {
display: none;
}
}
}

Loading…
Cancel
Save