Browse Source

Fix conflicting placeholder class name

master
Eduard Kuzmenko 3 years ago
parent
commit
c3fcca8af9
  1. 15
      src/components/chat/bubbles.ts
  2. 2
      src/config/app.ts
  3. 9
      src/helpers/dom/renderImageFromUrl.ts
  4. 7
      src/lang.ts
  5. 6
      src/lib/appManagers/appAvatarsManager.ts
  6. 90
      src/lib/appManagers/appDialogsManager.ts
  7. 6
      src/lib/appManagers/appPhotosManager.ts
  8. 35
      src/lib/langPack.ts
  9. 22
      src/scss/partials/_chatBubble.scss
  10. 21
      src/scss/partials/_leftSidebar.scss

15
src/components/chat/bubbles.ts

@ -3148,14 +3148,15 @@ export default class ChatBubbles {
} }
private renderEmptyPlaceholder(type: 'group' | 'saved' | 'noMessages' | 'noScheduledMessages' | 'greeting', bubble: HTMLElement, message: any, elements: (Node | string)[]) { private renderEmptyPlaceholder(type: 'group' | 'saved' | 'noMessages' | 'noScheduledMessages' | 'greeting', bubble: HTMLElement, message: any, elements: (Node | string)[]) {
bubble.classList.add('empty-placeholder', 'empty-placeholder-' + type); const BASE_CLASS = 'empty-bubble-placeholder';
bubble.classList.add(BASE_CLASS, BASE_CLASS + '-' + type);
let title: HTMLElement; let title: HTMLElement;
if(type === 'group') title = i18n('GroupEmptyTitle1'); if(type === 'group') title = i18n('GroupEmptyTitle1');
else if(type === 'saved') title = i18n('ChatYourSelfTitle'); else if(type === 'saved') title = i18n('ChatYourSelfTitle');
else if(type === 'noMessages' || type === 'greeting') title = i18n('NoMessages'); else if(type === 'noMessages' || type === 'greeting') title = i18n('NoMessages');
else if(type === 'noScheduledMessages') title = i18n('NoScheduledMessages'); else if(type === 'noScheduledMessages') title = i18n('NoScheduledMessages');
title.classList.add('center', 'empty-placeholder-title'); title.classList.add('center', BASE_CLASS + '-title');
elements.push(title); elements.push(title);
@ -3177,12 +3178,12 @@ export default class ChatBubbles {
]; ];
} else if(type === 'greeting') { } else if(type === 'greeting') {
const subtitle = i18n('NoMessagesGreetingsDescription'); const subtitle = i18n('NoMessagesGreetingsDescription');
subtitle.classList.add('center', 'empty-placeholder-subtitle'); subtitle.classList.add('center', BASE_CLASS + '-subtitle');
this.messagesQueue.findAndSplice(q => q.bubble === bubble); this.messagesQueue.findAndSplice(q => q.bubble === bubble);
const stickerDiv = document.createElement('div'); const stickerDiv = document.createElement('div');
stickerDiv.classList.add('empty-placeholder-sticker'); stickerDiv.classList.add(BASE_CLASS + '-sticker');
const middleware = this.getMiddleware(); const middleware = this.getMiddleware();
@ -3221,7 +3222,7 @@ export default class ChatBubbles {
elements.push( elements.push(
...listElements.map(elem => { ...listElements.map(elem => {
const span = document.createElement('span'); const span = document.createElement('span');
span.classList.add('empty-placeholder-list-item'); span.classList.add(BASE_CLASS + '-list-item');
span.append(elem); span.append(elem);
return span; return span;
}) })
@ -3236,7 +3237,7 @@ export default class ChatBubbles {
} else if(type === 'saved') { } else if(type === 'saved') {
listElements.forEach(elem => { listElements.forEach(elem => {
const i = document.createElement('span'); const i = document.createElement('span');
i.classList.add('empty-placeholder-list-bullet'); i.classList.add(BASE_CLASS + '-list-bullet');
i.innerText = '•'; i.innerText = '•';
elem.prepend(i); elem.prepend(i);
}); });
@ -3247,7 +3248,7 @@ export default class ChatBubbles {
bubble.classList.add('has-description'); bubble.classList.add('has-description');
} }
elements.forEach((element: any) => element.classList.add('empty-placeholder-line')); elements.forEach((element: any) => element.classList.add(BASE_CLASS + '-line'));
} }
private processLocalMessageRender(message: Message.message | Message.messageService) { private processLocalMessageRender(message: Message.message | Message.messageService) {

2
src/config/app.ts

@ -17,7 +17,7 @@ const App = {
id: 1025907, id: 1025907,
hash: '452b0359b988148995f22ff0f4229750', hash: '452b0359b988148995f22ff0f4229750',
version: '0.6.1', version: '0.6.1',
langPackVersion: '0.3.1', langPackVersion: '0.3.2',
langPack: 'macos', langPack: 'macos',
langPackCode: 'en', langPackCode: 'en',
domains: [MAIN_DOMAIN] as string[], domains: [MAIN_DOMAIN] as string[],

9
src/helpers/dom/renderImageFromUrl.ts

@ -12,7 +12,8 @@ const set = (elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoE
}; };
// проблема функции в том, что она не подходит для ссылок, пригодна только для blob'ов, потому что обычным ссылкам нужен 'load' каждый раз. // проблема функции в том, что она не подходит для ссылок, пригодна только для blob'ов, потому что обычным ссылкам нужен 'load' каждый раз.
export default async function renderImageFromUrl(elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoElement, url: string, callback?: (err?: Event) => void, useCache = true) { export default function renderImageFromUrl(elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoElement,
url: string, callback?: (err?: Event) => void, useCache = true) {
if(!url) { if(!url) {
console.error('renderImageFromUrl: no url?', elem, url); console.error('renderImageFromUrl: no url?', elem, url);
callback && callback(); callback && callback();
@ -54,3 +55,9 @@ export default async function renderImageFromUrl(elem: HTMLElement | HTMLImageEl
} }
} }
} }
export function renderImageFromUrlPromise(elem: Parameters<typeof renderImageFromUrl>[0], url: string, useCache?: boolean) {
return new Promise((resolve) => {
renderImageFromUrl(elem, url, resolve, useCache);
});
}

7
src/lang.ts

@ -43,6 +43,9 @@ const lang = {
}, },
"Chat.Search.NoMessagesFound": "No messages found", "Chat.Search.NoMessagesFound": "No messages found",
"Chat.Search.PrivateSearch": "Private Search", "Chat.Search.PrivateSearch": "Private Search",
"ChatList.Main.EmptyPlaceholder.Title": "Your chats will appear here",
"ChatList.Main.EmptyPlaceholder.Subtitle": "You have %s on Telegram",
"ChatList.Main.EmptyPlaceholder.SubtitleNoContacts": "Use Telegram app on your [Android](https://telegram.org/android) or [iOS](https://telegram.org/dl/ios) device to sync your contacts",
//"ChatList.Menu.Archived": "Archived", //"ChatList.Menu.Archived": "Archived",
"ChatList.Menu.SwitchTo.Webogram": "Switch to Old Version", "ChatList.Menu.SwitchTo.Webogram": "Switch to Old Version",
"ChatList.Menu.SwitchTo.Z": "Switch to Z version", "ChatList.Menu.SwitchTo.Z": "Switch to Z version",
@ -54,6 +57,10 @@ const lang = {
"ConnectionStatus.Reconnecting": "Reconnecting...", "ConnectionStatus.Reconnecting": "Reconnecting...",
"ConnectionStatus.TimedOut": "Request timed out, %s", "ConnectionStatus.TimedOut": "Request timed out, %s",
"ConnectionStatus.Waiting": "Waiting for network...", "ConnectionStatus.Waiting": "Waiting for network...",
"Contacts.Count": {
"one_value": "%d contact",
"other_value": "%d contacts",
},
"Deactivated.Title": "Too many tabs...", "Deactivated.Title": "Too many tabs...",
"Deactivated.Subtitle": "Telegram supports only one active tab with the app.\nClick anywhere to continue using this tab.", "Deactivated.Subtitle": "Telegram supports only one active tab with the app.\nClick anywhere to continue using this tab.",
/* "Drafts": { /* "Drafts": {

6
src/lib/appManagers/appAvatarsManager.ts

@ -4,7 +4,7 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE * https://github.com/morethanwords/tweb/blob/master/LICENSE
*/ */
import renderImageFromUrl from "../../helpers/dom/renderImageFromUrl"; import renderImageFromUrl, { renderImageFromUrlPromise } from "../../helpers/dom/renderImageFromUrl";
import replaceContent from "../../helpers/dom/replaceContent"; import replaceContent from "../../helpers/dom/replaceContent";
import sequentialDom from "../../helpers/sequentialDom"; import sequentialDom from "../../helpers/sequentialDom";
import { UserProfilePhoto, ChatPhoto, InputFileLocation } from "../../layer"; import { UserProfilePhoto, ChatPhoto, InputFileLocation } from "../../layer";
@ -103,7 +103,7 @@ export class AppAvatarsManager {
thumbImage.classList.add('avatar-photo', 'avatar-photo-thumbnail'); thumbImage.classList.add('avatar-photo', 'avatar-photo-thumbnail');
img.classList.add('avatar-photo'); img.classList.add('avatar-photo');
const url = appPhotosManager.getPreviewURLFromBytes(photo.stripped_thumb); const url = appPhotosManager.getPreviewURLFromBytes(photo.stripped_thumb);
renderThumbPromise = renderImageFromUrl(thumbImage, url).then(() => { renderThumbPromise = renderImageFromUrlPromise(thumbImage, url).then(() => {
replaceContent(div, thumbImage); replaceContent(div, thumbImage);
}); });
} }
@ -134,7 +134,7 @@ export class AppAvatarsManager {
} }
const renderPromise = loadPromise const renderPromise = loadPromise
.then((url) => renderImageFromUrl(img, url/* , false */)) .then((url) => renderImageFromUrlPromise(img, url/* , false */))
.then(() => callback()); .then(() => callback());
return {cached, loadPromise: renderThumbPromise || renderPromise}; return {cached, loadPromise: renderThumbPromise || renderPromise};

90
src/lib/appManagers/appDialogsManager.ts

@ -29,7 +29,7 @@ import appDraftsManager, { MyDraftMessage } from "./appDraftsManager";
import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug"; import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug";
import appNotificationsManager from "./appNotificationsManager"; import appNotificationsManager from "./appNotificationsManager";
import PeerTitle from "../../components/peerTitle"; import PeerTitle from "../../components/peerTitle";
import { i18n, LangPackKey, _i18n } from "../langPack"; import I18n, { FormatterArguments, i18n, LangPackKey, _i18n } from "../langPack";
import findUpTag from "../../helpers/dom/findUpTag"; import findUpTag from "../../helpers/dom/findUpTag";
import { LazyLoadQueueIntersector } from "../../components/lazyLoadQueue"; import { LazyLoadQueueIntersector } from "../../components/lazyLoadQueue";
import lottieLoader from "../lottieLoader"; import lottieLoader from "../lottieLoader";
@ -41,6 +41,8 @@ import positionElementByIndex from "../../helpers/dom/positionElementByIndex";
import replaceContent from "../../helpers/dom/replaceContent"; import replaceContent from "../../helpers/dom/replaceContent";
import ConnectionStatusComponent from "../../components/connectionStatus"; import ConnectionStatusComponent from "../../components/connectionStatus";
import appChatsManager from "./appChatsManager"; import appChatsManager from "./appChatsManager";
import { renderImageFromUrlPromise } from "../../helpers/dom/renderImageFromUrl";
import { fastRafPromise } from "../../helpers/schedulers";
export type DialogDom = { export type DialogDom = {
avatarEl: AvatarElement, avatarEl: AvatarElement,
@ -754,12 +756,13 @@ export class AppDialogsManager {
private generateEmptyPlaceholder(options: { private generateEmptyPlaceholder(options: {
title: LangPackKey, title: LangPackKey,
subtitle: LangPackKey, subtitle?: LangPackKey,
subtitleArgs?: FormatterArguments,
classNameType: string classNameType: string
}) { }) {
const BASE_CLASS = 'empty-placeholder'; const BASE_CLASS = 'empty-placeholder';
const div = document.createElement('div'); const container = document.createElement('div');
div.classList.add(BASE_CLASS, BASE_CLASS + '-' + options.classNameType); container.classList.add(BASE_CLASS, BASE_CLASS + '-' + options.classNameType);
const header = document.createElement('div'); const header = document.createElement('div');
header.classList.add(BASE_CLASS + '-header'); header.classList.add(BASE_CLASS + '-header');
@ -767,31 +770,82 @@ export class AppDialogsManager {
const subtitle = document.createElement('div'); const subtitle = document.createElement('div');
subtitle.classList.add(BASE_CLASS + '-subtitle'); subtitle.classList.add(BASE_CLASS + '-subtitle');
_i18n(subtitle, options.subtitle); if(options.subtitle) {
_i18n(subtitle, options.subtitle, options.subtitleArgs);
}
div.append(header, subtitle); container.append(header, subtitle);
return div; return {container, header, subtitle};
} }
private onListLengthChange = () => { private onListLengthChange = () => {
//return; //return;
if(this.filterId === 1) {
return;
}
if(this.filterId < 2) return; let placeholderContainer = (Array.from(this.chatList.parentElement.children) as HTMLElement[]).find(el => el.matches('.empty-placeholder'));
const needPlaceholder = this.scroll.loadedAll.bottom && !this.chatList.childElementCount/* || true */;
// this.chatList.style.display = 'none';
const emptyPlaceholder = this.chatList.parentElement.querySelector('.empty-placeholder'); if(needPlaceholder && placeholderContainer) {
if(this.scroll.loadedAll.bottom && !this.chatList.childElementCount) { return;
if(emptyPlaceholder) { } else if(!needPlaceholder) {
return; if(placeholderContainer) {
placeholderContainer.remove();
} }
const d = this.generateEmptyPlaceholder({ return;
}
let placeholder: ReturnType<AppDialogsManager['generateEmptyPlaceholder']>;
if(!this.filterId) {
placeholder = this.generateEmptyPlaceholder({
title: 'ChatList.Main.EmptyPlaceholder.Title',
classNameType: 'dialogs'
});
placeholderContainer = placeholder.container;
const img = document.createElement('img');
img.classList.add('empty-placeholder-dialogs-icon');
Promise.all([
appUsersManager.getContacts().then(users => {
let key: LangPackKey, args: FormatterArguments;
if(users.length) {
key = 'ChatList.Main.EmptyPlaceholder.Subtitle';
args = [i18n('Contacts.Count', [users.length])];
} else {
key = 'ChatList.Main.EmptyPlaceholder.SubtitleNoContacts';
args = [];
}
const subtitleEl = new I18n.IntlElement({
key,
args,
element: placeholder.subtitle
});
}),
renderImageFromUrlPromise(img, 'assets/img/EmptyChats.svg'),
fastRafPromise()
]).then(() => {
placeholderContainer.classList.add('visible');
});
placeholderContainer.prepend(img);
} else {
placeholder = this.generateEmptyPlaceholder({
title: 'FilterNoChatsToDisplay', title: 'FilterNoChatsToDisplay',
subtitle: 'FilterNoChatsToDisplayInfo', subtitle: 'FilterNoChatsToDisplayInfo',
classNameType: 'folder' classNameType: 'folder'
}); });
d.prepend(wrapLocalSticker({ placeholderContainer = placeholder.container;
placeholderContainer.prepend(wrapLocalSticker({
emoji: '📂', emoji: '📂',
width: 128, width: 128,
height: 128 height: 128
@ -806,12 +860,10 @@ export class AppDialogsManager {
new AppEditFolderTab(appSidebarLeft).open(appMessagesManager.filtersStorage.filters[this.filterId]); new AppEditFolderTab(appSidebarLeft).open(appMessagesManager.filtersStorage.filters[this.filterId]);
}); });
d.append(button); placeholderContainer.append(button);
this.chatList.parentElement.append(d);
} else if(emptyPlaceholder) {
emptyPlaceholder.remove();
} }
this.chatList.parentElement.append(placeholderContainer);
}; };
public onChatsRegularScroll = () => { public onChatsRegularScroll = () => {

6
src/lib/appManagers/appPhotosManager.ts

@ -23,7 +23,7 @@ import appDownloadManager, { ThumbCache } from "./appDownloadManager";
import appUsersManager from "./appUsersManager"; import appUsersManager from "./appUsersManager";
import blur from "../../helpers/blur"; import blur from "../../helpers/blur";
import { MOUNT_CLASS_TO } from "../../config/debug"; import { MOUNT_CLASS_TO } from "../../config/debug";
import renderImageFromUrl from "../../helpers/dom/renderImageFromUrl"; import { renderImageFromUrlPromise } from "../../helpers/dom/renderImageFromUrl";
import calcImageInBox from "../../helpers/calcImageInBox"; import calcImageInBox from "../../helpers/calcImageInBox";
import { makeMediaSize, MediaSize } from "../../helpers/mediaSizes"; import { makeMediaSize, MediaSize } from "../../helpers/mediaSizes";
@ -208,9 +208,7 @@ export class AppPhotosManager {
image.classList.add('thumbnail'); image.classList.add('thumbnail');
const loadPromise = (useBlur ? blur(url) : Promise.resolve(url)).then(url => { const loadPromise = (useBlur ? blur(url) : Promise.resolve(url)).then(url => {
return new Promise<any>((resolve) => { return renderImageFromUrlPromise(image, url);
renderImageFromUrl(image, url, resolve);
});
}); });
return {image, loadPromise}; return {image, loadPromise};

35
src/lib/langPack.ts

@ -14,6 +14,7 @@ import apiManager from "./mtproto/mtprotoworker";
import stateStorage from "./stateStorage"; import stateStorage from "./stateStorage";
import App from "../config/app"; import App from "../config/app";
import rootScope from "./rootScope"; import rootScope from "./rootScope";
import RichTextProcessor from "./richtextprocessor";
export const langPack: {[actionType: string]: LangPackKey} = { export const langPack: {[actionType: string]: LangPackKey} = {
"messageActionChatCreate": "ActionCreateGroup", "messageActionChatCreate": "ActionCreateGroup",
@ -59,6 +60,9 @@ export const langPack: {[actionType: string]: LangPackKey} = {
export type LangPackKey = /* string | */keyof typeof lang | keyof typeof langSign; export type LangPackKey = /* string | */keyof typeof lang | keyof typeof langSign;
export type FormatterArgument = string | Node;
export type FormatterArguments = FormatterArgument[];
namespace I18n { namespace I18n {
export const strings: Map<LangPackKey, LangPackString> = new Map(); export const strings: Map<LangPackKey, LangPackString> = new Map();
let pluralRules: Intl.PluralRules; let pluralRules: Intl.PluralRules;
@ -230,12 +234,12 @@ namespace I18n {
}); });
} }
export function superFormatter(input: string, args?: any[], indexHolder = {i: 0}) { export function superFormatter(input: string, args?: FormatterArguments, indexHolder = {i: 0}) {
let out: (string | HTMLElement)[] = []; let out: FormatterArguments = [];
const regExp = /(\*\*)(.+?)\1|(\n)|un\d|%\d\$.|%./g; const regExp = /(\*\*)(.+?)\1|(\n)|(\[.+?\]\(.*?\))|un\d|%\d\$.|%./g;
let lastIndex = 0; let lastIndex = 0;
input.replace(regExp, (match, p1: any, p2: any, p3: any, offset: number, string: string) => { input.replace(regExp, (match, p1: any, p2: any, p3: any, p4: string, offset: number, string: string) => {
//console.table({match, p1, p2, offset, string}); //console.table({match, p1, p2, offset, string});
out.push(string.slice(lastIndex, offset)); out.push(string.slice(lastIndex, offset));
@ -252,6 +256,23 @@ namespace I18n {
} }
} else if(p3) { } else if(p3) {
out.push(document.createElement('br')); out.push(document.createElement('br'));
} else if(p4) {
const a = document.createElement('a');
const idx = p4.lastIndexOf(']');
const text = p4.slice(1, idx);
a.append(...superFormatter(text, args, indexHolder));
const url = p4.slice(idx + 2, p4.length - 1);
if(url) {
const wrappedUrl = RichTextProcessor.wrapUrl(url);
a.href = wrappedUrl.url;
if(wrappedUrl.onclick) a.setAttribute('onclick', wrappedUrl.onclick);
a.target = '_blank';
}
out.push(a);
console.log('p4', p4);
} else if(args) { } else if(args) {
out.push(args[indexHolder.i++]); out.push(args[indexHolder.i++]);
} }
@ -268,8 +289,8 @@ namespace I18n {
} }
export function format(key: LangPackKey, plain: true, args?: any[]): string; export function format(key: LangPackKey, plain: true, args?: any[]): string;
export function format(key: LangPackKey, plain?: false, args?: any[]): (string | HTMLElement)[]; export function format(key: LangPackKey, plain?: false, args?: any[]): FormatterArguments;
export function format(key: LangPackKey, plain = false, args?: any[]): (string | HTMLElement)[] | string { export function format(key: LangPackKey, plain = false, args?: any[]): FormatterArguments | string {
const str = strings.get(key); const str = strings.get(key);
let input: string; let input: string;
if(str) { if(str) {
@ -329,7 +350,7 @@ namespace I18n {
export type IntlElementOptions = IntlElementBaseOptions & { export type IntlElementOptions = IntlElementBaseOptions & {
key: LangPackKey, key: LangPackKey,
args?: any[] args?: FormatterArguments
}; };
export class IntlElement extends IntlElementBase<IntlElementOptions> { export class IntlElement extends IntlElementBase<IntlElementOptions> {
public key: IntlElementOptions['key']; public key: IntlElementOptions['key'];

22
src/scss/partials/_chatBubble.scss

@ -733,7 +733,7 @@ $bubble-margin: .25rem;
max-width: 100%; max-width: 100%;
} }
&.empty-placeholder { &.empty-bubble-placeholder {
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
@ -750,7 +750,7 @@ $bubble-margin: .25rem;
align-self: center; align-self: center;
} }
.empty-placeholder-title { .empty-bubble-placeholder-title {
font-weight: 500; font-weight: 500;
font-size: 1rem !important; font-size: 1rem !important;
} }
@ -760,7 +760,11 @@ $bubble-margin: .25rem;
} }
} }
.empty-placeholder-line + .empty-placeholder-line { .empty-bubble-placeholder-line {
color: #fff;
}
.empty-bubble-placeholder-line + .empty-bubble-placeholder-line {
margin-top: .5rem; margin-top: .5rem;
} }
@ -771,7 +775,7 @@ $bubble-margin: .25rem;
margin-left: -.1875rem; margin-left: -.1875rem;
} }
.empty-placeholder-list-bullet { .empty-bubble-placeholder-list-bullet {
margin-right: .3125rem; margin-right: .3125rem;
} }
@ -784,23 +788,23 @@ $bubble-margin: .25rem;
} }
} }
&.empty-placeholder-group { &.empty-bubble-placeholder-group {
.empty-placeholder-list-item { .empty-bubble-placeholder-list-item {
margin-top: .4375rem !important; margin-top: .4375rem !important;
} }
} }
&.empty-placeholder-greeting { &.empty-bubble-placeholder-greeting {
.service-msg { .service-msg {
max-width: 232px; max-width: 232px;
} }
.empty-placeholder-subtitle { .empty-bubble-placeholder-subtitle {
margin-top: .25rem !important; margin-top: .25rem !important;
} }
} }
.empty-placeholder-sticker { .empty-bubble-placeholder-sticker {
margin-top: .75rem !important; margin-top: .75rem !important;
position: relative; position: relative;
width: 200px; width: 200px;

21
src/scss/partials/_leftSidebar.scss

@ -1187,6 +1187,9 @@
text-align: center; text-align: center;
line-height: var(--line-height); line-height: var(--line-height);
user-select: none; user-select: none;
width: 21rem !important;
margin: 0 auto;
padding: 0 1rem;
.media-sticker-wrapper { .media-sticker-wrapper {
width: 128px; width: 128px;
@ -1203,7 +1206,7 @@
&-subtitle { &-subtitle {
color: var(--secondary-text-color); color: var(--secondary-text-color);
font-size: .875rem; font-size: .875rem;
margin-top: .3125rem; margin-top: .375rem;
} }
.btn-control { .btn-control {
@ -1214,4 +1217,20 @@
margin-right: .625rem; margin-right: .625rem;
} }
} }
&-dialogs {
opacity: 0;
@include animation-level(2) {
transition: opacity .2s ease-in-out;
}
&-icon {
margin-bottom: 1.0625rem;
}
&.visible {
opacity: 1;
}
}
} }

Loading…
Cancel
Save