Dark Theme
This commit is contained in:
parent
b37ec8bca2
commit
ee1b137d0e
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
dist
|
||||||
.cache
|
.cache
|
||||||
.env
|
.env
|
||||||
src/lib/gramjs/build/
|
src/lib/gramjs/build/
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
|
import { withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ApiAudio, ApiMessage, ApiVoice,
|
ApiAudio, ApiMessage, ApiVoice,
|
||||||
} from '../../api/types';
|
} from '../../api/types';
|
||||||
|
import { ISettings } from '../../types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
||||||
import { formatMediaDateTime, formatMediaDuration, formatPastTimeShort } from '../../util/dateFormat';
|
import { formatMediaDateTime, formatMediaDuration, formatPastTimeShort } from '../../util/dateFormat';
|
||||||
@ -49,6 +51,10 @@ type OwnProps = {
|
|||||||
onDateClick?: (messageId: number, chatId: number) => void;
|
onDateClick?: (messageId: number, chatId: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type StateProps = {
|
||||||
|
theme: ISettings['theme'];
|
||||||
|
};
|
||||||
|
|
||||||
interface ISeekMethods {
|
interface ISeekMethods {
|
||||||
handleStartSeek: (e: React.MouseEvent<HTMLElement>) => void;
|
handleStartSeek: (e: React.MouseEvent<HTMLElement>) => void;
|
||||||
handleSeek: (e: React.MouseEvent<HTMLElement>) => void;
|
handleSeek: (e: React.MouseEvent<HTMLElement>) => void;
|
||||||
@ -61,7 +67,8 @@ const MAX_SPIKES = IS_MOBILE_SCREEN ? 50 : 75;
|
|||||||
// This is needed for browsers requiring user interaction before playing.
|
// This is needed for browsers requiring user interaction before playing.
|
||||||
const PRELOAD = true;
|
const PRELOAD = true;
|
||||||
|
|
||||||
const Audio: FC<OwnProps> = ({
|
const Audio: FC<OwnProps & StateProps> = ({
|
||||||
|
theme,
|
||||||
message,
|
message,
|
||||||
senderTitle,
|
senderTitle,
|
||||||
uploadProgress,
|
uploadProgress,
|
||||||
@ -201,8 +208,8 @@ const Audio: FC<OwnProps> = ({
|
|||||||
const seekHandlers = { handleStartSeek, handleSeek, handleStopSeek };
|
const seekHandlers = { handleStartSeek, handleSeek, handleStopSeek };
|
||||||
const isOwn = isOwnMessage(message);
|
const isOwn = isOwnMessage(message);
|
||||||
const renderedWaveform = useMemo(
|
const renderedWaveform = useMemo(
|
||||||
() => voice && renderWaveform(voice, playProgress, isOwn, seekHandlers),
|
() => voice && renderWaveform(voice, playProgress, isOwn, seekHandlers, theme),
|
||||||
[voice, playProgress, isOwn, seekHandlers],
|
[voice, playProgress, isOwn, seekHandlers, theme],
|
||||||
);
|
);
|
||||||
|
|
||||||
const fullClassName = buildClassName(
|
const fullClassName = buildClassName(
|
||||||
@ -346,7 +353,11 @@ function renderVoice(voice: ApiVoice, renderedWaveform: any, isMediaUnread?: boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderWaveform(
|
function renderWaveform(
|
||||||
voice: ApiVoice, playProgress = 0, isOwn = false, { handleStartSeek, handleSeek, handleStopSeek }: ISeekMethods,
|
voice: ApiVoice,
|
||||||
|
playProgress = 0,
|
||||||
|
isOwn = false,
|
||||||
|
{ handleStartSeek, handleSeek, handleStopSeek }: ISeekMethods,
|
||||||
|
theme: ISettings['theme'],
|
||||||
) {
|
) {
|
||||||
const { waveform, duration } = voice;
|
const { waveform, duration } = voice;
|
||||||
|
|
||||||
@ -354,14 +365,18 @@ function renderWaveform(
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fillColor = theme === 'dark' ? '#494B75' : '#CBCBCB';
|
||||||
|
const fillOwnColor = theme === 'dark' ? '#C69C85' : '#B0DEA6';
|
||||||
|
const progressFillColor = theme === 'dark' ? '#868DF5' : '#54a3e6';
|
||||||
|
const progressFillOwnColor = theme === 'dark' ? '#FFFFFF' : '#53ad53';
|
||||||
const durationFactor = Math.min(duration / AVG_VOICE_DURATION, 1);
|
const durationFactor = Math.min(duration / AVG_VOICE_DURATION, 1);
|
||||||
const spikesCount = Math.round(MIN_SPIKES + (MAX_SPIKES - MIN_SPIKES) * durationFactor);
|
const spikesCount = Math.round(MIN_SPIKES + (MAX_SPIKES - MIN_SPIKES) * durationFactor);
|
||||||
const decodedWaveform = decodeWaveform(new Uint8Array(waveform));
|
const decodedWaveform = decodeWaveform(new Uint8Array(waveform));
|
||||||
const { data: spikes, peak } = interpolateArray(decodedWaveform, spikesCount);
|
const { data: spikes, peak } = interpolateArray(decodedWaveform, spikesCount);
|
||||||
const { src, width, height } = renderWaveformToDataUri(spikes, playProgress, {
|
const { src, width, height } = renderWaveformToDataUri(spikes, playProgress, {
|
||||||
peak,
|
peak,
|
||||||
fillStyle: isOwn ? '#B0DEA6' : '#CBCBCB',
|
fillStyle: isOwn ? fillOwnColor : fillColor,
|
||||||
progressFillStyle: isOwn ? '#53ad53' : '#54a3e6',
|
progressFillStyle: isOwn ? progressFillOwnColor : progressFillColor,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -414,4 +429,4 @@ function renderSeekline(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default memo(Audio);
|
export default memo(withGlobal<OwnProps>((global) => ({ theme: global.settings.byKey.theme }))(Audio));
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
width: 3.375rem;
|
width: 3.375rem;
|
||||||
height: 3.375rem;
|
height: 3.375rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: linear-gradient(white -125%, var(--color-user));
|
background: linear-gradient(var(--color-white) -125%, var(--color-user));
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -109,7 +109,7 @@
|
|||||||
width: 0.875rem;
|
width: 0.875rem;
|
||||||
height: 0.875rem;
|
height: 0.875rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 2px solid white;
|
border: 2px solid var(--color-background);
|
||||||
background-color: #0ac630;
|
background-color: #0ac630;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
left: .625rem;
|
left: .625rem;
|
||||||
|
|||||||
@ -158,7 +158,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.smaller {
|
&.smaller {
|
||||||
--background-color: #fff;
|
--background-color: var(--color-background);
|
||||||
--border-radius-messages-small: .3125rem;
|
--border-radius-messages-small: .3125rem;
|
||||||
|
|
||||||
.icon-download,
|
.icon-download,
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.MessageOutgoingStatus {
|
.MessageOutgoingStatus {
|
||||||
color: var(--color-text-green);
|
color: var(--color-text-meta-colored);
|
||||||
margin-right: 0.1rem;
|
margin-right: 0.1rem;
|
||||||
font-size: 1.15rem;
|
font-size: 1.15rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
.button-wrapper {
|
.button-wrapper {
|
||||||
padding: 0.5rem 0;
|
padding: 0.5rem 0;
|
||||||
border-top: 1px solid var(--color-borders);
|
border-top: 1px solid var(--color-borders);
|
||||||
box-shadow: 0 0 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 0 2px var(--color-default-shadow);
|
||||||
|
|
||||||
button {
|
button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
.left {
|
.left {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
min-width: 15.5rem;
|
min-width: 15.5rem;
|
||||||
max-width: 26.5rem;
|
max-width: 26.5rem;
|
||||||
|
|
||||||
@ -56,10 +56,19 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
background: rgb(230, 235, 238) url('../../assets/chat-bg.jpg') no-repeat center;
|
background: no-repeat center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
transform-origin: left center;
|
transform-origin: left center;
|
||||||
|
|
||||||
|
.theme-dark body.initial & {
|
||||||
|
background-color: #0f0f0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-light body.initial &,
|
||||||
|
body:not(.initial) & {
|
||||||
|
background-image: url('../../assets/chat-bg.jpg');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.with-right-column::before {
|
&.with-right-column::before {
|
||||||
@ -97,12 +106,12 @@
|
|||||||
min-width: 15.5rem;
|
min-width: 15.5rem;
|
||||||
max-width: 26.5rem;
|
max-width: 26.5rem;
|
||||||
border-left: 1px solid var(--color-borders);
|
border-left: 1px solid var(--color-borders);
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.blank {
|
.blank {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ type OwnProps = {
|
|||||||
|
|
||||||
type StateProps = Pick<GlobalState, 'uiReadyState'> & {
|
type StateProps = Pick<GlobalState, 'uiReadyState'> & {
|
||||||
hasCustomBackground?: boolean;
|
hasCustomBackground?: boolean;
|
||||||
|
isCustomBackgroundColor: boolean;
|
||||||
isRightColumnShown?: boolean;
|
isRightColumnShown?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -84,6 +85,7 @@ const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
page,
|
page,
|
||||||
children,
|
children,
|
||||||
hasCustomBackground,
|
hasCustomBackground,
|
||||||
|
isCustomBackgroundColor,
|
||||||
isRightColumnShown,
|
isRightColumnShown,
|
||||||
setIsUiReady,
|
setIsUiReady,
|
||||||
}) => {
|
}) => {
|
||||||
@ -129,7 +131,8 @@ const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
<div
|
<div
|
||||||
className={buildClassName(
|
className={buildClassName(
|
||||||
'middle',
|
'middle',
|
||||||
hasCustomBackground && 'custom-bg-image',
|
hasCustomBackground && !isCustomBackgroundColor && 'custom-bg-image',
|
||||||
|
hasCustomBackground && isCustomBackgroundColor && 'custom-bg-color',
|
||||||
isRightColumnShown && 'with-right-column',
|
isRightColumnShown && 'with-right-column',
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@ -149,6 +152,7 @@ export default withGlobal<OwnProps>(
|
|||||||
return {
|
return {
|
||||||
uiReadyState: global.uiReadyState,
|
uiReadyState: global.uiReadyState,
|
||||||
hasCustomBackground: Boolean(global.settings.byKey.customBackground),
|
hasCustomBackground: Boolean(global.settings.byKey.customBackground),
|
||||||
|
isCustomBackgroundColor: Boolean((global.settings.byKey.customBackground || '').match(/^#[a-f\d]{6,8}$/i)),
|
||||||
isRightColumnShown: selectIsRightColumnShown(global),
|
isRightColumnShown: selectIsRightColumnShown(global),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
.Chat {
|
.Chat {
|
||||||
--background-color: white;
|
--background-color: var(--color-background);
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|||||||
@ -118,7 +118,6 @@ const LeftMain: FC<OwnProps & StateProps> = ({
|
|||||||
onSearchQuery={onSearchQuery}
|
onSearchQuery={onSearchQuery}
|
||||||
onSelectSettings={handleSelectSettings}
|
onSelectSettings={handleSelectSettings}
|
||||||
onSelectContacts={handleSelectContacts}
|
onSelectContacts={handleSelectContacts}
|
||||||
onSelectNewGroup={handleSelectNewGroup}
|
|
||||||
onSelectArchived={handleSelectArchived}
|
onSelectArchived={handleSelectArchived}
|
||||||
onReset={onReset}
|
onReset={onReset}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -45,7 +45,7 @@
|
|||||||
.archived-badge {
|
.archived-badge {
|
||||||
min-width: 1.5rem;
|
min-width: 1.5rem;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
margin-left: 2rem;
|
margin-left: auto;
|
||||||
background: var(--color-gray);
|
background: var(--color-gray);
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
padding: 0 .45rem;
|
padding: 0 .45rem;
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import React, {
|
|||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { GlobalActions } from '../../../global/types';
|
import { GlobalActions } from '../../../global/types';
|
||||||
import { LeftColumnContent } from '../../../types';
|
import { LeftColumnContent, ISettings } from '../../../types';
|
||||||
import { ApiChat } from '../../../api/types';
|
import { ApiChat } from '../../../api/types';
|
||||||
|
|
||||||
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
import { IS_MOBILE_SCREEN } from '../../../util/environment';
|
||||||
@ -12,6 +12,7 @@ import buildClassName from '../../../util/buildClassName';
|
|||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
import { isChatArchived } from '../../../modules/helpers';
|
import { isChatArchived } from '../../../modules/helpers';
|
||||||
import { formatDateToString } from '../../../util/dateFormat';
|
import { formatDateToString } from '../../../util/dateFormat';
|
||||||
|
import switchTheme from '../../../util/switchTheme';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
|
|
||||||
import DropdownMenu from '../../ui/DropdownMenu';
|
import DropdownMenu from '../../ui/DropdownMenu';
|
||||||
@ -19,6 +20,7 @@ import MenuItem from '../../ui/MenuItem';
|
|||||||
import Button from '../../ui/Button';
|
import Button from '../../ui/Button';
|
||||||
import SearchInput from '../../ui/SearchInput';
|
import SearchInput from '../../ui/SearchInput';
|
||||||
import PickerSelectedItem from '../../common/PickerSelectedItem';
|
import PickerSelectedItem from '../../common/PickerSelectedItem';
|
||||||
|
import Switcher from '../../ui/Switcher';
|
||||||
|
|
||||||
import './LeftMainHeader.scss';
|
import './LeftMainHeader.scss';
|
||||||
|
|
||||||
@ -28,7 +30,6 @@ type OwnProps = {
|
|||||||
onSearchQuery: (query: string) => void;
|
onSearchQuery: (query: string) => void;
|
||||||
onSelectSettings: () => void;
|
onSelectSettings: () => void;
|
||||||
onSelectContacts: () => void;
|
onSelectContacts: () => void;
|
||||||
onSelectNewGroup: () => void;
|
|
||||||
onSelectArchived: () => void;
|
onSelectArchived: () => void;
|
||||||
onReset: () => void;
|
onReset: () => void;
|
||||||
};
|
};
|
||||||
@ -39,11 +40,15 @@ type StateProps = {
|
|||||||
currentUserId?: number;
|
currentUserId?: number;
|
||||||
globalSearchChatId?: number;
|
globalSearchChatId?: number;
|
||||||
searchDate?: number;
|
searchDate?: number;
|
||||||
|
theme: ISettings['theme'];
|
||||||
|
animationLevel: 0 | 1 | 2;
|
||||||
chatsById?: Record<number, ApiChat>;
|
chatsById?: Record<number, ApiChat>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions,
|
type DispatchProps = Pick<GlobalActions,
|
||||||
'openChat'| 'openSupportChat' | 'setGlobalSearchDate' | 'setGlobalSearchChatId'>;
|
'openChat'| 'openSupportChat' | 'setGlobalSearchDate' | 'setGlobalSearchChatId' | 'setSettingOption'>;
|
||||||
|
|
||||||
|
const ANIMATION_LEVEL_OPTIONS = [0, 1, 2];
|
||||||
|
|
||||||
const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||||
content,
|
content,
|
||||||
@ -51,7 +56,6 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
onSearchQuery,
|
onSearchQuery,
|
||||||
onSelectSettings,
|
onSelectSettings,
|
||||||
onSelectContacts,
|
onSelectContacts,
|
||||||
onSelectNewGroup,
|
|
||||||
onSelectArchived,
|
onSelectArchived,
|
||||||
setGlobalSearchChatId,
|
setGlobalSearchChatId,
|
||||||
onReset,
|
onReset,
|
||||||
@ -60,10 +64,13 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
currentUserId,
|
currentUserId,
|
||||||
globalSearchChatId,
|
globalSearchChatId,
|
||||||
searchDate,
|
searchDate,
|
||||||
|
theme,
|
||||||
|
animationLevel,
|
||||||
chatsById,
|
chatsById,
|
||||||
openChat,
|
openChat,
|
||||||
openSupportChat,
|
openSupportChat,
|
||||||
setGlobalSearchDate,
|
setGlobalSearchDate,
|
||||||
|
setSettingOption,
|
||||||
}) => {
|
}) => {
|
||||||
const hasMenu = content === LeftColumnContent.ChatList;
|
const hasMenu = content === LeftColumnContent.ChatList;
|
||||||
const clearedDateSearchParam = { date: undefined };
|
const clearedDateSearchParam = { date: undefined };
|
||||||
@ -113,6 +120,28 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
openChat({ id: currentUserId });
|
openChat({ id: currentUserId });
|
||||||
}, [currentUserId, openChat]);
|
}, [currentUserId, openChat]);
|
||||||
|
|
||||||
|
const handleDarkModeToggle = useCallback((e: React.SyntheticEvent<HTMLDivElement>) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
const newTheme = theme === 'light' ? 'dark' : 'light';
|
||||||
|
|
||||||
|
setSettingOption({
|
||||||
|
theme: newTheme,
|
||||||
|
customBackground: newTheme === 'dark' ? '#0F0F0F' : undefined,
|
||||||
|
});
|
||||||
|
switchTheme(newTheme, animationLevel > 0);
|
||||||
|
}, [animationLevel, setSettingOption, theme]);
|
||||||
|
|
||||||
|
const handleAnimationLevelChange = useCallback((e: React.SyntheticEvent<HTMLDivElement>) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const newLevel = animationLevel === 0 ? 2 : 0;
|
||||||
|
ANIMATION_LEVEL_OPTIONS.forEach((_, i) => {
|
||||||
|
document.body.classList.toggle(`animation-level-${i}`, newLevel === i);
|
||||||
|
});
|
||||||
|
|
||||||
|
setSettingOption({ animationLevel: newLevel });
|
||||||
|
}, [animationLevel, setSettingOption]);
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const isSearchFocused = Boolean(globalSearchChatId)
|
const isSearchFocused = Boolean(globalSearchChatId)
|
||||||
@ -130,10 +159,19 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
trigger={MainButton}
|
trigger={MainButton}
|
||||||
>
|
>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="group"
|
icon="saved-messages"
|
||||||
onClick={onSelectNewGroup}
|
onClick={handleSelectSaved}
|
||||||
>
|
>
|
||||||
{lang('NewGroup')}
|
{lang('SavedMessages')}
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
icon="archive"
|
||||||
|
onClick={onSelectArchived}
|
||||||
|
>
|
||||||
|
<span className="menu-item-name">{lang('ArchivedChats')}</span>
|
||||||
|
{archivedUnreadChatsCount > 0 && (
|
||||||
|
<div className="archived-badge">{archivedUnreadChatsCount}</div>
|
||||||
|
)}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="user"
|
icon="user"
|
||||||
@ -141,27 +179,34 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
>
|
>
|
||||||
{lang('Contacts')}
|
{lang('Contacts')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
|
||||||
icon="archive"
|
|
||||||
onClick={onSelectArchived}
|
|
||||||
>
|
|
||||||
{lang('Archived')}
|
|
||||||
{archivedUnreadChatsCount > 0 && (
|
|
||||||
<div className="archived-badge">{archivedUnreadChatsCount}</div>
|
|
||||||
)}
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
icon="saved-messages"
|
|
||||||
onClick={handleSelectSaved}
|
|
||||||
>
|
|
||||||
{lang('Saved')}
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="settings"
|
icon="settings"
|
||||||
onClick={onSelectSettings}
|
onClick={onSelectSettings}
|
||||||
>
|
>
|
||||||
{lang('Settings')}
|
{lang('Settings')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
icon="darkmode"
|
||||||
|
onClick={handleDarkModeToggle}
|
||||||
|
>
|
||||||
|
<span className="menu-item-name">Dark Mode</span>
|
||||||
|
<Switcher
|
||||||
|
id="darkmode"
|
||||||
|
label="Toggle Dark Mode"
|
||||||
|
checked={theme === 'dark'}
|
||||||
|
/>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
icon="animations"
|
||||||
|
onClick={handleAnimationLevelChange}
|
||||||
|
>
|
||||||
|
<span className="menu-item-name">{lang('SettingsSearch.Synonyms.Appearance.Animations')}</span>
|
||||||
|
<Switcher
|
||||||
|
id="animations"
|
||||||
|
label="Toggle Animations"
|
||||||
|
checked={animationLevel > 0}
|
||||||
|
/>
|
||||||
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="help"
|
icon="help"
|
||||||
onClick={openSupportChat}
|
onClick={openSupportChat}
|
||||||
@ -213,6 +258,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
} = global.globalSearch;
|
} = global.globalSearch;
|
||||||
const { currentUserId } = global;
|
const { currentUserId } = global;
|
||||||
const { byId: chatsById } = global.chats;
|
const { byId: chatsById } = global.chats;
|
||||||
|
const { theme, animationLevel } = global.settings.byKey;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
searchQuery,
|
searchQuery,
|
||||||
@ -221,6 +267,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
chatsById,
|
chatsById,
|
||||||
globalSearchChatId: chatId,
|
globalSearchChatId: chatId,
|
||||||
searchDate: date,
|
searchDate: date,
|
||||||
|
theme,
|
||||||
|
animationLevel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||||
@ -228,5 +276,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
'openSupportChat',
|
'openSupportChat',
|
||||||
'setGlobalSearchDate',
|
'setGlobalSearchDate',
|
||||||
'setGlobalSearchChatId',
|
'setGlobalSearchChatId',
|
||||||
|
'setSettingOption',
|
||||||
]),
|
]),
|
||||||
)(LeftMainHeader));
|
)(LeftMainHeader));
|
||||||
|
|||||||
@ -163,7 +163,7 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
box-shadow: inset 0 -1px 0 0 var(--color-borders);
|
box-shadow: inset 0 -1px 0 0 var(--color-borders);
|
||||||
background-color: white;
|
background-color: var(--color-background);
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
left: -0.75rem;
|
left: -0.75rem;
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
border: 0.125rem solid white;
|
border: 0.125rem solid var(--color-white);
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
@ -66,12 +66,12 @@
|
|||||||
|
|
||||||
div {
|
div {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: inset 0 0 0 0 white;
|
box-shadow: inset 0 0 0 0 var(--color-background);
|
||||||
transition: box-shadow 300ms ease;
|
transition: box-shadow 300ms ease;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
border: 0.125rem solid var(--color-primary);
|
border: 0.125rem solid var(--color-primary);
|
||||||
box-shadow: inset 0 0 0 0.3125rem white;
|
box-shadow: inset 0 0 0 0.3125rem var(--color-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A hack to make a square
|
// A hack to make a square
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
height: calc(100% - var(--header-height));
|
height: calc(100% - var(--header-height));
|
||||||
|
|
||||||
.picker-header {
|
.picker-header {
|
||||||
box-shadow: 0 0 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 0 2px var(--color-default-shadow);
|
||||||
|
|
||||||
.max-items-reached {
|
.max-items-reached {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { pick } from '../../util/iteratees';
|
|||||||
import { selectIsForwardModalOpen, selectIsMediaViewerOpen, selectIsRightColumnShown } from '../../modules/selectors';
|
import { selectIsForwardModalOpen, selectIsMediaViewerOpen, selectIsRightColumnShown } from '../../modules/selectors';
|
||||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
|
||||||
import LeftColumn from '../left/LeftColumn';
|
import LeftColumn from '../left/LeftColumn';
|
||||||
import MiddleColumn from '../middle/MiddleColumn';
|
import MiddleColumn from '../middle/MiddleColumn';
|
||||||
@ -19,7 +20,6 @@ import Notifications from './Notifications.async';
|
|||||||
import Errors from './Errors.async';
|
import Errors from './Errors.async';
|
||||||
|
|
||||||
import './Main.scss';
|
import './Main.scss';
|
||||||
import buildClassName from '../../util/buildClassName';
|
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
animationLevel: number;
|
animationLevel: number;
|
||||||
|
|||||||
@ -74,7 +74,7 @@
|
|||||||
width: .75rem;
|
width: .75rem;
|
||||||
height: .75rem;
|
height: .75rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #fff;
|
background-color: var(--color-white);
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translate(.325rem, -50%);
|
transform: translate(.325rem, -50%);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
const units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
|
const units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
|
||||||
|
|
||||||
export default (bytes: number) => {
|
export default (bytes: number) => {
|
||||||
const number = Math.floor(Math.log(bytes) / Math.log(1024));
|
const number = bytes === 0 ? 0 : Math.floor(Math.log(bytes) / Math.log(1024));
|
||||||
|
|
||||||
return `${(bytes / 1024 ** Math.floor(number)).toFixed(1)} ${units[number]}`;
|
return `${(bytes / 1024 ** Math.floor(number)).toFixed(1)} ${units[number]}`;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,14 +5,17 @@
|
|||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: overlay;
|
overflow-y: overlay;
|
||||||
|
padding-bottom: .3125rem;
|
||||||
|
|
||||||
body.hide-mask-shadow .mask-image-disabled &,
|
body.hide-mask-shadow .mask-image-disabled &,
|
||||||
.mask-image-enabled & {
|
.mask-image-enabled & {
|
||||||
mask-image: linear-gradient(to top, transparent 0, #000 1rem);
|
mask-image: linear-gradient(to top, transparent 0, #000 1rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-bg-color.mask-image-disabled &,
|
||||||
.custom-bg-image.mask-image-disabled & {
|
.custom-bg-image.mask-image-disabled & {
|
||||||
margin-bottom: .3rem;
|
margin-bottom: .3125rem;
|
||||||
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (pointer: coarse) {
|
@media (pointer: coarse) {
|
||||||
|
|||||||
@ -77,9 +77,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
|
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
border-radius: var(--border-radius-messages);
|
border-radius: var(--border-radius-messages);
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
|
|||||||
@ -7,7 +7,8 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|
||||||
&::before {
|
&::before,
|
||||||
|
&::after {
|
||||||
content: "";
|
content: "";
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -15,13 +16,18 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
background-color: rgb(230, 235, 238);
|
background-color: #F2EBCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
background-image: url('../../assets/chat-bg.jpg');
|
background-image: url('../../assets/chat-bg.jpg');
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
|
|
||||||
transition: background-image .3s ease;
|
.disable-animations #root & {
|
||||||
|
transition: opacity .2s !important;
|
||||||
|
}
|
||||||
|
|
||||||
body.animation-level-0 & {
|
body.animation-level-0 & {
|
||||||
transition: none;
|
transition: none;
|
||||||
@ -32,19 +38,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-bg-image > &::before {
|
.custom-bg-image > &::after {
|
||||||
background-image: var(--custom-background) !important;
|
background-image: var(--custom-background) !important;
|
||||||
|
filter: blur(0);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-bg-color > &::before {
|
||||||
background-color: var(--custom-background) !important;
|
background-color: var(--custom-background) !important;
|
||||||
filter: blur(0);
|
filter: blur(0);
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-bg-image.blurred > &::before {
|
.custom-bg-image.blurred > &::after {
|
||||||
filter: blur(12px);
|
filter: blur(12px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-bg-color > &::after {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1276px) {
|
@media screen and (min-width: 1276px) {
|
||||||
body.animation-level-2 &::before {
|
body.animation-level-2 &::before,
|
||||||
|
body.animation-level-2 &::after {
|
||||||
margin: -16rem -5rem -20rem 0;
|
margin: -16rem -5rem -20rem 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
@ -52,12 +68,12 @@
|
|||||||
transition: transform var(--layer-transition);
|
transition: transform var(--layer-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.animation-level-2 .custom-bg-image > &::before {
|
body.animation-level-2 .custom-bg-image > &::after {
|
||||||
margin: -16rem -5rem -20rem -1rem;
|
margin: -16rem -5rem -20rem -1rem;
|
||||||
transition: transform var(--layer-transition), background .3s ease;
|
transition: transform var(--layer-transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.animation-level-2 #Main.right-column-open :not(.custom-bg-image) > &::before {
|
body.animation-level-2 #Main.right-column-open :not(.custom-bg-image) > &::after {
|
||||||
transform: scale(0.67);
|
transform: scale(0.67);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,10 +117,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: var(--border-radius-messages);
|
border-radius: var(--border-radius-messages);
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,6 +328,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-bg-color &::before,
|
||||||
.custom-bg-image &::before {
|
.custom-bg-image &::before {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -330,7 +347,7 @@
|
|||||||
color: var(--color-black);
|
color: var(--color-black);
|
||||||
height: 3.125rem;
|
height: 3.125rem;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.icon-unpin {
|
.icon-unpin {
|
||||||
|
|||||||
@ -59,6 +59,7 @@ type StateProps = {
|
|||||||
messageSendingRestrictionReason?: string;
|
messageSendingRestrictionReason?: string;
|
||||||
hasPinnedOrAudioMessage?: boolean;
|
hasPinnedOrAudioMessage?: boolean;
|
||||||
customBackground?: string;
|
customBackground?: string;
|
||||||
|
isCustomBackgroundColor?: boolean;
|
||||||
isRightColumnShown?: boolean;
|
isRightColumnShown?: boolean;
|
||||||
isBackgroundBlurred?: boolean;
|
isBackgroundBlurred?: boolean;
|
||||||
isMobileSearchActive?: boolean;
|
isMobileSearchActive?: boolean;
|
||||||
@ -84,6 +85,7 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
|||||||
messageSendingRestrictionReason,
|
messageSendingRestrictionReason,
|
||||||
hasPinnedOrAudioMessage,
|
hasPinnedOrAudioMessage,
|
||||||
customBackground,
|
customBackground,
|
||||||
|
isCustomBackgroundColor,
|
||||||
isRightColumnShown,
|
isRightColumnShown,
|
||||||
isBackgroundBlurred,
|
isBackgroundBlurred,
|
||||||
isMobileSearchActive,
|
isMobileSearchActive,
|
||||||
@ -166,7 +168,8 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
const className = buildClassName(
|
const className = buildClassName(
|
||||||
hasTools && 'has-header-tools',
|
hasTools && 'has-header-tools',
|
||||||
customBackground && 'custom-bg-image',
|
customBackground && !isCustomBackgroundColor && 'custom-bg-image',
|
||||||
|
customBackground && isCustomBackgroundColor && 'custom-bg-color',
|
||||||
customBackground && isBackgroundBlurred && 'blurred',
|
customBackground && isBackgroundBlurred && 'blurred',
|
||||||
MASK_IMAGE_ENABLED ? 'mask-image-enabled' : 'mask-image-disabled',
|
MASK_IMAGE_ENABLED ? 'mask-image-enabled' : 'mask-image-disabled',
|
||||||
);
|
);
|
||||||
@ -293,12 +296,14 @@ export default memo(withGlobal(
|
|||||||
(global): StateProps => {
|
(global): StateProps => {
|
||||||
const { isBackgroundBlurred, customBackground } = global.settings.byKey;
|
const { isBackgroundBlurred, customBackground } = global.settings.byKey;
|
||||||
|
|
||||||
|
const isCustomBackgroundColor = Boolean((customBackground || '').match(/^#[a-f\d]{6,8}$/i));
|
||||||
const currentMessageList = selectCurrentMessageList(global);
|
const currentMessageList = selectCurrentMessageList(global);
|
||||||
const { chats: { listIds } } = global;
|
const { chats: { listIds } } = global;
|
||||||
if (!currentMessageList || !listIds.active) {
|
if (!currentMessageList || !listIds.active) {
|
||||||
return {
|
return {
|
||||||
customBackground,
|
customBackground,
|
||||||
isBackgroundBlurred,
|
isBackgroundBlurred,
|
||||||
|
isCustomBackgroundColor,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,6 +325,7 @@ export default memo(withGlobal(
|
|||||||
messageSendingRestrictionReason: chat && getMessageSendingRestrictionReason(chat),
|
messageSendingRestrictionReason: chat && getMessageSendingRestrictionReason(chat),
|
||||||
hasPinnedOrAudioMessage: Boolean(pinnedIds && pinnedIds.length) || Boolean(audioChatId && audioMessageId),
|
hasPinnedOrAudioMessage: Boolean(pinnedIds && pinnedIds.length) || Boolean(audioChatId && audioMessageId),
|
||||||
customBackground,
|
customBackground,
|
||||||
|
isCustomBackgroundColor,
|
||||||
isRightColumnShown: selectIsRightColumnShown(global),
|
isRightColumnShown: selectIsRightColumnShown(global),
|
||||||
isBackgroundBlurred,
|
isBackgroundBlurred,
|
||||||
isMobileSearchActive: Boolean(IS_MOBILE_SCREEN && selectCurrentTextSearch(global)),
|
isMobileSearchActive: Boolean(IS_MOBILE_SCREEN && selectCurrentTextSearch(global)),
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
height: 2.875rem;
|
height: 2.875rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 2px 2px rgba(114, 114, 114, 0.17);
|
box-shadow: 0 2px 2px var(--color-light-shadow);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
@ -25,7 +25,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
box-shadow: 0 2px 2px rgba(114, 114, 114, 0.17);
|
box-shadow: 0 2px 2px var(--color-light-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.HeaderPinnedMessage {
|
.HeaderPinnedMessage {
|
||||||
@ -73,8 +73,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: 0 2px 2px rgba(114, 114, 114, 0.17);
|
box-shadow: 0 2px 2px var(--color-light-shadow);
|
||||||
background: #fff;
|
background: var(--color-background);
|
||||||
padding: .5rem .8125rem .5rem 1.5rem;
|
padding: .5rem .8125rem .5rem 1.5rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: var(--z-middle-header);
|
z-index: var(--z-middle-header);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
z-index: var(--z-mobile-search);
|
z-index: var(--z-mobile-search);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 3.5rem;
|
height: 3.5rem;
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 0.5rem 0 0.25rem;
|
padding: 0 0.5rem 0 0.25rem;
|
||||||
@ -23,7 +23,7 @@
|
|||||||
z-index: var(--z-mobile-search);
|
z-index: var(--z-mobile-search);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 3.5rem;
|
height: 3.5rem;
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
> .Button {
|
> .Button {
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
|
|
||||||
i {
|
i {
|
||||||
font-size: 1.75rem;
|
font-size: 1.75rem;
|
||||||
|
|||||||
@ -66,7 +66,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.form-control {
|
.form-control {
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.MentionMenu {
|
.MentionMenu {
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
min-height: 3.0625rem;
|
min-height: 3.0625rem;
|
||||||
border-radius: var(--border-radius-messages-small);
|
border-radius: var(--border-radius-messages-small);
|
||||||
border: 2px solid var(--color-primary);
|
border: 2px solid var(--color-primary);
|
||||||
background: #fff;
|
background: var(--color-background);
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
|
|||||||
@ -150,10 +150,10 @@
|
|||||||
#message-compose {
|
#message-compose {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
max-width: calc(100% - 4rem);
|
max-width: calc(100% - 4rem);
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
border-radius: var(--border-radius-messages);
|
border-radius: var(--border-radius-messages);
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
@ -169,6 +169,10 @@
|
|||||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOSIgaGVpZ2h0PSIyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGRlZnM+PGZpbHRlciB4PSItNTAlIiB5PSItMTQuNyUiIHdpZHRoPSIyMDAlIiBoZWlnaHQ9IjE0MS4yJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0iYSI+PGZlT2Zmc2V0IGR5PSIxIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMSIgaW49InNoYWRvd09mZnNldE91dGVyMSIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDAuMDYyMTk2MjQ4MiAwIDAgMCAwIDAuMTM4NTc0MTQ0IDAgMCAwIDAgMC4xODUwMzczNjQgMCAwIDAgMC4xNSAwIiBpbj0ic2hhZG93Qmx1ck91dGVyMSIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik0zIDE3aDZWMGMtLjE5MyAyLjg0LS44NzYgNS43NjctMi4wNSA4Ljc4Mi0uOTA0IDIuMzI1LTIuNDQ2IDQuNDg1LTQuNjI1IDYuNDhBMSAxIDAgMDAzIDE3eiIgaWQ9ImIiLz48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PC9nPjwvc3ZnPg==);
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOSIgaGVpZ2h0PSIyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGRlZnM+PGZpbHRlciB4PSItNTAlIiB5PSItMTQuNyUiIHdpZHRoPSIyMDAlIiBoZWlnaHQ9IjE0MS4yJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0iYSI+PGZlT2Zmc2V0IGR5PSIxIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMSIgaW49InNoYWRvd09mZnNldE91dGVyMSIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDAuMDYyMTk2MjQ4MiAwIDAgMCAwIDAuMTM4NTc0MTQ0IDAgMCAwIDAgMC4xODUwMzczNjQgMCAwIDAgMC4xNSAwIiBpbj0ic2hhZG93Qmx1ck91dGVyMSIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik0zIDE3aDZWMGMtLjE5MyAyLjg0LS44NzYgNS43NjctMi4wNSA4Ljc4Mi0uOTA0IDIuMzI1LTIuNDQ2IDQuNDg1LTQuNjI1IDYuNDhBMSAxIDAgMDAzIDE3eiIgaWQ9ImIiLz48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PC9nPjwvc3ZnPg==);
|
||||||
background-position: bottom left;
|
background-position: bottom left;
|
||||||
transform: scaleX(-1);
|
transform: scaleX(-1);
|
||||||
|
|
||||||
|
.theme-dark & {
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOSIgaGVpZ2h0PSIyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48ZmlsdGVyIGlkPSJhIiB4PSIwIiB5PSIwIiB3aWR0aD0iMjA1IiBoZWlnaHQ9IjIwMCI+PGZlT2Zmc2V0IHJlc3VsdD0ib2ZmT3V0IiBpbj0iU291cmNlQWxwaGEiIGR5PSIxIi8+PGZlQ29sb3JNYXRyaXggcmVzdWx0PSJtYXRyaXhPdXQiIGluPSJvZmZPdXQiIHZhbHVlcz0iMC4xMyAwIDAgMCAwIDAgMC4xMyAwIDAgMCAwIDAgMC4xMyAwIDAgMCAwIDAgMC42IDAiLz48ZmVHYXVzc2lhbkJsdXIgcmVzdWx0PSJibHVyT3V0IiBpbj0ibWF0cml4T3V0IiBzdGREZXZpYXRpb249IjEiLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJibHVyT3V0Ii8+PC9maWx0ZXI+PC9kZWZzPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0iTTMgMTdoNlYwYy0uMTkzIDIuODQtLjg3NiA1Ljc2Ny0yLjA1IDguNzgyLS45MDQgMi4zMjUtMi40NDYgNC40ODUtNC42MjUgNi40OEExIDEgMCAwMDMgMTd6IiBmaWxsPSIjMDAwIiBmaWx0ZXI9InVybCgjYSkiLz48cGF0aCBkPSJNMyAxN2g2VjBjLS4xOTMgMi44NC0uODc2IDUuNzY3LTIuMDUgOC43ODItLjkwNCAyLjMyNS0yLjQ0NiA0LjQ4NS00LjYyNSA2LjQ4QTEgMSAwIDAwMyAxN3oiIGZpbGw9IiMyMTIxMjEiLz48L2c+PC9zdmc+);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
@ -203,13 +207,13 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: .75rem;
|
top: .75rem;
|
||||||
right: .75rem;
|
right: .75rem;
|
||||||
border: .1875rem solid #fff;
|
border: .1875rem solid var(--color-background);
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
width: .5rem;
|
width: .5rem;
|
||||||
height: .5rem;
|
height: .5rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--color-green-darker);
|
background: var(--color-green-darker);
|
||||||
box-shadow: -.375rem -.25rem 0 -.1875rem #fff;
|
box-shadow: -.375rem -.25rem 0 -.1875rem var(--color-background);
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
top: .5rem;
|
top: .5rem;
|
||||||
right: .5rem;
|
right: .5rem;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
.DropTarget {
|
.DropTarget {
|
||||||
border-radius: var(--border-radius-default);
|
border-radius: var(--border-radius-default);
|
||||||
background: #fff;
|
background: var(--color-background);
|
||||||
padding: 1.25rem;
|
padding: 1.25rem;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -10,7 +10,7 @@
|
|||||||
margin-bottom: .3125rem;
|
margin-bottom: .3125rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
color: #A4ACB3;
|
color: #A4ACB3;
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
|
|
||||||
@media (max-height: 350px) {
|
@media (max-height: 350px) {
|
||||||
padding: .75rem;
|
padding: .75rem;
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
box-shadow: 0 0 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 0 2px var(--color-default-shadow);
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
bottom: calc(100% + .5rem);
|
bottom: calc(100% + .5rem);
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
border-radius: var(--border-radius-messages);
|
border-radius: var(--border-radius-messages);
|
||||||
padding: 0.5rem 0;
|
padding: 0.5rem 0;
|
||||||
max-height: 15rem;
|
max-height: 15rem;
|
||||||
@ -15,7 +15,7 @@
|
|||||||
grid-auto-rows: auto;
|
grid-auto-rows: auto;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
|
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(1.5rem);
|
transform: translateY(1.5rem);
|
||||||
|
|||||||
@ -4,14 +4,14 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: calc(100% - 4rem);
|
width: calc(100% - 4rem);
|
||||||
max-width: 20rem;
|
max-width: 20rem;
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
border-radius: var(--border-radius-messages);
|
border-radius: var(--border-radius-messages);
|
||||||
padding: 0.5rem 0;
|
padding: 0.5rem 0;
|
||||||
max-height: 15rem;
|
max-height: 15rem;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
box-shadow: 3px 3px 5px rgba(114, 114, 114, 0.25);
|
box-shadow: 3px 3px 5px var(--color-default-shadow);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
box-shadow: 0 0 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 0 2px var(--color-default-shadow);
|
||||||
|
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
scrollbar-color: rgba(0, 0, 0, 0);
|
scrollbar-color: rgba(0, 0, 0, 0);
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
box-shadow: 0 0 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 0 2px var(--color-default-shadow);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.Button {
|
.Button {
|
||||||
|
|||||||
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
&, &-link-control {
|
&, &-link-control {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
border-radius: var(--border-radius-messages);
|
border-radius: var(--border-radius-messages);
|
||||||
padding: 0.5rem 0.375rem;
|
padding: 0.5rem 0.375rem;
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
&-link-control {
|
&-link-control {
|
||||||
@ -24,6 +24,8 @@
|
|||||||
border: none !important;
|
border: none !important;
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
color: var(--color-text);
|
||||||
|
background-color: var(--color-background);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,12 +64,12 @@
|
|||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
left: 0;
|
left: 0;
|
||||||
background: linear-gradient(to right, #fff .25rem, transparent 1rem)
|
background: linear-gradient(to right, var(--color-background) .25rem, transparent 1rem)
|
||||||
}
|
}
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
right: 0;
|
right: 0;
|
||||||
background: linear-gradient(to left, #fff .25rem, transparent 1rem)
|
background: linear-gradient(to left, var(--color-background) .25rem, transparent 1rem)
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mask-left {
|
&.mask-left {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
.CommentButton {
|
.CommentButton {
|
||||||
--background-color: #fff;
|
--background-color: var(--color-background);
|
||||||
--hover-color: #f4f4f4;
|
--hover-color: var(--color-chat-hover);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -30,9 +30,13 @@
|
|||||||
width: .5625rem;
|
width: .5625rem;
|
||||||
height: 1.25rem;
|
height: 1.25rem;
|
||||||
background-position: bottom left;
|
background-position: bottom left;
|
||||||
background-image: url("data:image/svg+xml,%3Csvg width='9' height='20' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cdefs%3E%3Cfilter x='-50%25' y='-14.7%25' width='200%25' height='141.2%25' filterUnits='objectBoundingBox' id='a'%3E%3CfeOffset dy='1' in='SourceAlpha' result='shadowOffsetOuter1'/%3E%3CfeGaussianBlur stdDeviation='1' in='shadowOffsetOuter1' result='shadowBlurOuter1'/%3E%3CfeColorMatrix values='0 0 0 0 0.0621962482 0 0 0 0 0.138574144 0 0 0 0 0.185037364 0 0 0 0.15 0' in='shadowBlurOuter1'/%3E%3C/filter%3E%3Cpath d='M3 17h6V0c-.193 2.84-.876 5.767-2.05 8.782-.904 2.325-2.446 4.485-4.625 6.48A1 1 0 003 17z' id='b'/%3E%3C/defs%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cuse fill='%23000' filter='url(%23a)' xlink:href='%23b'/%3E%3Cuse fill='%23f4f4f4' xlink:href='%23b'/%3E%3C/g%3E%3C/svg%3E");
|
background-image: url('data:image/svg+xml,%3Csvg width="9" height="20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"%3E%3Cdefs%3E%3Cfilter x="-50%25" y="-14.7%25" width="200%25" height="141.2%25" filterUnits="objectBoundingBox" id="a"%3E%3CfeOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/%3E%3CfeGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"/%3E%3CfeColorMatrix values="0 0 0 0 0.0621962482 0 0 0 0 0.138574144 0 0 0 0 0.185037364 0 0 0 0.15 0" in="shadowBlurOuter1"/%3E%3C/filter%3E%3Cpath d="M3 17h6V0c-.193 2.84-.876 5.767-2.05 8.782-.904 2.325-2.446 4.485-4.625 6.48A1 1 0 003 17z" id="b"/%3E%3C/defs%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cuse fill="%23000" filter="url(%23a)" xlink:href="%23b"/%3E%3Cuse fill="%23FFF" xlink:href="%23b"/%3E%3C/g%3E%3C/svg%3E');
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity .15s;
|
transition: opacity .15s, filter .15s;
|
||||||
|
|
||||||
|
.theme-dark #root & {
|
||||||
|
filter: invert(.83);
|
||||||
|
}
|
||||||
|
|
||||||
body.animation-level-0 & {
|
body.animation-level-0 & {
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
@ -162,7 +166,7 @@
|
|||||||
|
|
||||||
.Avatar {
|
.Avatar {
|
||||||
transition: border .15s;
|
transition: border .15s;
|
||||||
border: 2px solid #fff;
|
border: 2px solid var(--color-background);
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
margin: .25rem;
|
margin: .25rem;
|
||||||
background-color: rgba(90, 110, 70, 0.6);
|
background-color: rgba(90, 110, 70, 0.6);
|
||||||
border-radius: var(--border-radius-messages-small);
|
border-radius: var(--border-radius-messages-small);
|
||||||
color: var(--color-white);
|
color: var(--color-text);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
margin-bottom: 0.375rem;
|
margin-bottom: 0.375rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
--background-color: white;
|
--background-color: var(--color-background);
|
||||||
--hover-color: rgba(var(--color-text-secondary-rgb), 0.08);
|
--hover-color: rgba(var(--color-text-secondary-rgb), 0.08);
|
||||||
--active-color: rgba(var(--color-text-secondary-rgb), 0.16);
|
--active-color: rgba(var(--color-text-secondary-rgb), 0.16);
|
||||||
--max-width: 29rem;
|
--max-width: 29rem;
|
||||||
@ -81,16 +81,19 @@
|
|||||||
&.own {
|
&.own {
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
--background-color: var(--color-background-own);
|
--background-color: var(--color-background-own);
|
||||||
--hover-color: rgba(var(--color-text-green-rgb), 0.12);
|
--hover-color: var(--color-reply-own-hover);
|
||||||
--active-color: rgba(var(--color-text-green-rgb), 0.24);
|
--active-color: var(--color-reply-own-active);
|
||||||
--max-width: 30rem;
|
--max-width: 30rem;
|
||||||
--accent-color: var(--color-text-green);
|
--accent-color: var(--color-accent-own);
|
||||||
--accent-shade-color: var(--color-green);
|
--accent-shade-color: var(--color-green);
|
||||||
--secondary-color: var(--color-text-green);
|
--secondary-color: var(--color-accent-own);
|
||||||
--color-code: var(--color-code-own);
|
--color-code: var(--color-code-own);
|
||||||
--color-code-bg: var(--color-code-own-bg);
|
--color-code-bg: var(--color-code-own-bg);
|
||||||
|
--color-links: var(--color-own-links);
|
||||||
|
--color-links-hover: var(--color-own-links);
|
||||||
--meta-safe-area-base: 3.5rem;
|
--meta-safe-area-base: 3.5rem;
|
||||||
--deleting-translate-x: 50%;
|
--deleting-translate-x: 50%;
|
||||||
|
--color-text-green: var(--color-accent-own);
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
padding-right: 0.25rem;
|
padding-right: 0.25rem;
|
||||||
@ -177,6 +180,15 @@
|
|||||||
bottom: 0.813rem;
|
bottom: 0.813rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html.theme-dark &.own .Audio .ProgressSpinner {
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUiIGhlaWdodD0iMTUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTguMjE4IDcuNWw1LjYzMy01LjYzM2EuNTA4LjUwOCAwIDEwLS43MTgtLjcxOEw3LjUgNi43ODIgMS44NjcgMS4xNDlhLjUwOC41MDggMCAxMC0uNzE4LjcxOEw2Ljc4MiA3LjVsLTUuNjMzIDUuNjMzYS41MDguNTA4IDAgMTAuNzE4LjcxOEw3LjUgOC4yMThsNS42MzMgNS42MzNhLjUwNi41MDYgMCAwMC43MTggMCAuNTA4LjUwOCAwIDAwMC0uNzE4TDguMjE4IDcuNXoiIGZpbGw9IiNGRkYiIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlPSIjQTQ1RDM3IiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PC9zdmc+);
|
||||||
|
|
||||||
|
circle {
|
||||||
|
stroke: var(--background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.File {
|
.File {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
|||||||
@ -72,12 +72,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.Message.own .has-solid-background & {
|
.Message.own .has-solid-background & {
|
||||||
color: var(--color-text-green);
|
color: var(--color-message-meta-own);
|
||||||
}
|
}
|
||||||
|
|
||||||
.MessageOutgoingStatus {
|
.MessageOutgoingStatus {
|
||||||
margin-left: -.1875rem;
|
margin-left: -.1875rem;
|
||||||
font-size: 1.1875rem;
|
font-size: 1.1875rem;
|
||||||
|
.Message.own & {
|
||||||
|
color: var(--color-accent-own);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-content.has-replies:not(.custom-shape) & {
|
.message-content.has-replies:not(.custom-shape) & {
|
||||||
|
|||||||
@ -109,7 +109,7 @@
|
|||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
|
|
||||||
.Avatar {
|
.Avatar {
|
||||||
border: 1px solid #fff;
|
border: 1px solid var(--color-white);
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
background: var(--accent-color);
|
background: var(--accent-color);
|
||||||
color: #fff;
|
color: var(--background-color);
|
||||||
border-radius: .5rem;
|
border-radius: .5rem;
|
||||||
font-size: .75rem;
|
font-size: .75rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@ -98,7 +98,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.has-shadow {
|
&.has-shadow {
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.has-solid-background, .is-album & {
|
&.has-solid-background, .is-album & {
|
||||||
@ -123,6 +123,10 @@
|
|||||||
background-position: bottom right;
|
background-position: bottom right;
|
||||||
background-image: url('data:image/svg+xml,%3Csvg width="9" height="20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"%3E%3Cdefs%3E%3Cfilter x="-50%25" y="-14.7%25" width="200%25" height="141.2%25" filterUnits="objectBoundingBox" id="a"%3E%3CfeOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/%3E%3CfeGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"/%3E%3CfeColorMatrix values="0 0 0 0 0.0621962482 0 0 0 0 0.138574144 0 0 0 0 0.185037364 0 0 0 0.15 0" in="shadowBlurOuter1"/%3E%3C/filter%3E%3Cpath d="M6 17H0V0c.193 2.84.876 5.767 2.05 8.782.904 2.325 2.446 4.485 4.625 6.48A1 1 0 016 17z" id="b"/%3E%3C/defs%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cuse fill="%23000" filter="url(%23a)" xlink:href="%23b"/%3E%3Cuse fill="%23EEFFDE" xlink:href="%23b"/%3E%3C/g%3E%3C/svg%3E');
|
background-image: url('data:image/svg+xml,%3Csvg width="9" height="20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"%3E%3Cdefs%3E%3Cfilter x="-50%25" y="-14.7%25" width="200%25" height="141.2%25" filterUnits="objectBoundingBox" id="a"%3E%3CfeOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/%3E%3CfeGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"/%3E%3CfeColorMatrix values="0 0 0 0 0.0621962482 0 0 0 0 0.138574144 0 0 0 0 0.185037364 0 0 0 0.15 0" in="shadowBlurOuter1"/%3E%3C/filter%3E%3Cpath d="M6 17H0V0c.193 2.84.876 5.767 2.05 8.782.904 2.325 2.446 4.485 4.625 6.48A1 1 0 016 17z" id="b"/%3E%3C/defs%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cuse fill="%23000" filter="url(%23a)" xlink:href="%23b"/%3E%3Cuse fill="%23EEFFDE" xlink:href="%23b"/%3E%3C/g%3E%3C/svg%3E');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-dark &:not([data-has-custom-appendix])::before {
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOSIgaGVpZ2h0PSIyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGRlZnM+PGZpbHRlciBpZD0iYSIgeD0iMCIgeT0iMCIgd2lkdGg9IjIwNSIgaGVpZ2h0PSIyMDAiPjxmZU9mZnNldCByZXN1bHQ9Im9mZk91dCIgaW49IlNvdXJjZUFscGhhIiBkeD0iLTEiIGR5PSIxIi8+PGZlQ29sb3JNYXRyaXggcmVzdWx0PSJtYXRyaXhPdXQiIGluPSJvZmZPdXQiIHZhbHVlcz0iMC4xMyAwIDAgMCAwIDAgMC4xMyAwIDAgMCAwIDAgMC4xMyAwIDAgMCAwIDAgMC42IDAiLz48ZmVHYXVzc2lhbkJsdXIgcmVzdWx0PSJibHVyT3V0IiBpbj0ibWF0cml4T3V0IiBzdGREZXZpYXRpb249IjEiLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJibHVyT3V0Ii8+PC9maWx0ZXI+PHBhdGggZD0iTTYgMTdIMFYwYy4xOTMgMi44NC44NzYgNS43NjcgMi4wNSA4Ljc4Mi45MDQgMi4zMjUgMi40NDYgNC40ODUgNC42MjUgNi40OEExIDEgMCAwMTYgMTd6IiBpZD0iYiIvPjwvZGVmcz48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjx1c2UgZmlsbD0iIzAwMCIgZmlsdGVyPSJ1cmwoI2EpIiB4bGluazpocmVmPSIjYiIvPjx1c2UgZmlsbD0iIzlBNUYzRiIgeGxpbms6aHJlZj0iI2IiLz48L2c+PC9zdmc+);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.Message:not(.own) & {
|
.Message:not(.own) & {
|
||||||
@ -131,6 +135,10 @@
|
|||||||
background-position: bottom left;
|
background-position: bottom left;
|
||||||
background-image: url('data:image/svg+xml,%3Csvg width="9" height="20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"%3E%3Cdefs%3E%3Cfilter x="-50%25" y="-14.7%25" width="200%25" height="141.2%25" filterUnits="objectBoundingBox" id="a"%3E%3CfeOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/%3E%3CfeGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"/%3E%3CfeColorMatrix values="0 0 0 0 0.0621962482 0 0 0 0 0.138574144 0 0 0 0 0.185037364 0 0 0 0.15 0" in="shadowBlurOuter1"/%3E%3C/filter%3E%3Cpath d="M3 17h6V0c-.193 2.84-.876 5.767-2.05 8.782-.904 2.325-2.446 4.485-4.625 6.48A1 1 0 003 17z" id="b"/%3E%3C/defs%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cuse fill="%23000" filter="url(%23a)" xlink:href="%23b"/%3E%3Cuse fill="%23FFF" xlink:href="%23b"/%3E%3C/g%3E%3C/svg%3E');
|
background-image: url('data:image/svg+xml,%3Csvg width="9" height="20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"%3E%3Cdefs%3E%3Cfilter x="-50%25" y="-14.7%25" width="200%25" height="141.2%25" filterUnits="objectBoundingBox" id="a"%3E%3CfeOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/%3E%3CfeGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"/%3E%3CfeColorMatrix values="0 0 0 0 0.0621962482 0 0 0 0 0.138574144 0 0 0 0 0.185037364 0 0 0 0.15 0" in="shadowBlurOuter1"/%3E%3C/filter%3E%3Cpath d="M3 17h6V0c-.193 2.84-.876 5.767-2.05 8.782-.904 2.325-2.446 4.485-4.625 6.48A1 1 0 003 17z" id="b"/%3E%3C/defs%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cuse fill="%23000" filter="url(%23a)" xlink:href="%23b"/%3E%3Cuse fill="%23FFF" xlink:href="%23b"/%3E%3C/g%3E%3C/svg%3E');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-dark &:not([data-has-custom-appendix])::before {
|
||||||
|
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOSIgaGVpZ2h0PSIyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48ZmlsdGVyIGlkPSJhIiB4PSIwIiB5PSIwIiB3aWR0aD0iMjA1IiBoZWlnaHQ9IjIwMCI+PGZlT2Zmc2V0IHJlc3VsdD0ib2ZmT3V0IiBpbj0iU291cmNlQWxwaGEiIGR5PSIxIi8+PGZlQ29sb3JNYXRyaXggcmVzdWx0PSJtYXRyaXhPdXQiIGluPSJvZmZPdXQiIHZhbHVlcz0iMC4xMyAwIDAgMCAwIDAgMC4xMyAwIDAgMCAwIDAgMC4xMyAwIDAgMCAwIDAgMC42IDAiLz48ZmVHYXVzc2lhbkJsdXIgcmVzdWx0PSJibHVyT3V0IiBpbj0ibWF0cml4T3V0IiBzdGREZXZpYXRpb249IjEiLz48ZmVCbGVuZCBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJibHVyT3V0Ii8+PC9maWx0ZXI+PC9kZWZzPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0iTTMgMTdoNlYwYy0uMTkzIDIuODQtLjg3NiA1Ljc2Ny0yLjA1IDguNzgyLS45MDQgMi4zMjUtMi40NDYgNC40ODUtNC42MjUgNi40OEExIDEgMCAwMDMgMTd6IiBmaWxsPSIjMDAwIiBmaWx0ZXI9InVybCgjYSkiLz48cGF0aCBkPSJNMyAxN2g2VjBjLS4xOTMgMi44NC0uODc2IDUuNzY3LTIuMDUgOC43ODItLjkwNCAyLjMyNS0yLjQ0NiA0LjQ4NS00LjYyNSA2LjQ4QTEgMSAwIDAwMyAxN3oiIGZpbGw9IiMyMTIxMjEiLz48L2c+PC9zdmc+);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.has-solid-background) {
|
&:not(.has-solid-background) {
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
border-bottom: 1px var(--color-borders) solid;
|
border-bottom: 1px var(--color-borders) solid;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
@ -51,7 +51,7 @@
|
|||||||
border-bottom-right-radius: 10px;
|
border-bottom-right-radius: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: .75rem 1rem;
|
padding: .75rem 1rem;
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
border-top: 1px var(--color-borders) solid;
|
border-top: 1px var(--color-borders) solid;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
padding: 1rem .75rem .5rem 1rem;
|
padding: 1rem .75rem .5rem 1rem;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: #fff;
|
background: var(--color-background);
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
padding: .5rem .25rem .5rem .5rem;
|
padding: .5rem .25rem .5rem .5rem;
|
||||||
|
|||||||
@ -51,7 +51,7 @@
|
|||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
|
|
||||||
.TabList {
|
.TabList {
|
||||||
background: #fff;
|
background: var(--color-background);
|
||||||
top: -1px;
|
top: -1px;
|
||||||
.Tab {
|
.Tab {
|
||||||
padding: .6875rem .25rem;
|
padding: .6875rem .25rem;
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1275px) {
|
@media (max-width: 1275px) {
|
||||||
box-shadow: 0 .25rem .5rem .1rem rgba(114, 114, 114, 0.25);
|
box-shadow: 0 .25rem .5rem .1rem var(--color-default-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.filled {
|
&.filled {
|
||||||
background-color: white;
|
background-color: var(--color-background);
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
|
|||||||
@ -79,7 +79,7 @@
|
|||||||
&::before {
|
&::before {
|
||||||
border: 2px solid var(--color-borders);
|
border: 2px solid var(--color-borders);
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
background-color: white;
|
background-color: var(--color-white);
|
||||||
transition: border-color .1s ease;
|
transition: border-color .1s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 1rem;
|
bottom: 1rem;
|
||||||
right: 1rem;
|
right: 1rem;
|
||||||
box-shadow: 0 1px 2px rgba(114, 114, 114, 0.25);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
#avatar-crop {
|
#avatar-crop {
|
||||||
|
|||||||
@ -19,8 +19,8 @@
|
|||||||
padding: 0.5rem 0;
|
padding: 0.5rem 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: white;
|
background-color: var(--color-background);
|
||||||
box-shadow: 0 .25rem .5rem .1rem rgba(114, 114, 114, 0.25);
|
box-shadow: 0 .25rem .5rem .1rem var(--color-default-shadow);
|
||||||
border-radius: var(--border-radius-default);
|
border-radius: var(--border-radius-default);
|
||||||
min-width: 13.5rem;
|
min-width: 13.5rem;
|
||||||
z-index: var(--z-menu-bubble);
|
z-index: var(--z-menu-bubble);
|
||||||
|
|||||||
@ -24,6 +24,10 @@
|
|||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu-item-name {
|
||||||
|
margin-right: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
opacity: 0.5 !important;
|
opacity: 0.5 !important;
|
||||||
cursor: default !important;
|
cursor: default !important;
|
||||||
@ -41,4 +45,8 @@
|
|||||||
background-color: var(--color-chat-active);
|
background-color: var(--color-chat-active);
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > .Switcher {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,8 +47,8 @@
|
|||||||
max-width: 35rem;
|
max-width: 35rem;
|
||||||
min-width: 17.5rem;
|
min-width: 17.5rem;
|
||||||
margin: 2rem auto;
|
margin: 2rem auto;
|
||||||
background-color: white;
|
background-color: var(--color-background);
|
||||||
box-shadow: 0 .25rem .5rem .1rem rgba(114, 114, 114, 0.25);
|
box-shadow: 0 .25rem .5rem .1rem var(--color-default-shadow);
|
||||||
border-radius: var(--border-radius-default);
|
border-radius: var(--border-radius-default);
|
||||||
transform: translate3d(0, -1rem, 0);
|
transform: translate3d(0, -1rem, 0);
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
&::before {
|
&::before {
|
||||||
border: 2px solid var(--color-borders);
|
border: 2px solid var(--color-borders);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: white;
|
background-color: var(--color-white);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: border-color .1s ease, opacity .1s ease;
|
transition: border-color .1s ease, opacity .1s ease;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
&.has-focus {
|
&.has-focus {
|
||||||
border-color: var(--color-primary);
|
border-color: var(--color-primary);
|
||||||
caret-color: var(--color-primary);
|
caret-color: var(--color-primary);
|
||||||
background-color: #fff;
|
background-color: var(--color-background);
|
||||||
|
|
||||||
input {
|
input {
|
||||||
& + i {
|
& + i {
|
||||||
|
|||||||
53
src/components/ui/Switcher.scss
Normal file
53
src/components/ui/Switcher.scss
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
.Switcher {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
z-index: var(--z-below);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget {
|
||||||
|
cursor: pointer;
|
||||||
|
text-indent: -999px;
|
||||||
|
width: 2.125rem;
|
||||||
|
height: 0.875rem;
|
||||||
|
background: var(--color-gray);
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: .5rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -.125rem;
|
||||||
|
left: 0;
|
||||||
|
width: 1.125rem;
|
||||||
|
height: 1.125rem;
|
||||||
|
background: var(--color-background);
|
||||||
|
border-radius: .75rem;
|
||||||
|
border: .125rem solid var(--color-gray);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .widget {
|
||||||
|
background: var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .widget:after {
|
||||||
|
left: calc(100% - 1.125rem);
|
||||||
|
transform: translateX(calc(-100% + 1.125rem));
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/components/ui/Switcher.tsx
Normal file
60
src/components/ui/Switcher.tsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { ChangeEvent } from 'react';
|
||||||
|
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
|
||||||
|
|
||||||
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
|
||||||
|
import './Switcher.scss';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
value?: string;
|
||||||
|
label: string;
|
||||||
|
checked?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
|
||||||
|
onCheck?: (isChecked: boolean) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Switcher: FC<OwnProps> = ({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
checked = false,
|
||||||
|
disabled,
|
||||||
|
onChange,
|
||||||
|
onCheck,
|
||||||
|
}) => {
|
||||||
|
const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (onChange) {
|
||||||
|
onChange(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onCheck) {
|
||||||
|
onCheck(event.currentTarget.checked);
|
||||||
|
}
|
||||||
|
}, [onChange, onCheck]);
|
||||||
|
|
||||||
|
const className = buildClassName(
|
||||||
|
'Switcher',
|
||||||
|
disabled && 'disabled',
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<label className={className} title={label}>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id={id}
|
||||||
|
name={name}
|
||||||
|
value={value}
|
||||||
|
checked={checked}
|
||||||
|
disabled={disabled}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
<span className="widget" />
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(Switcher);
|
||||||
@ -7,8 +7,8 @@
|
|||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
box-shadow: 0 2px 2px rgba(114, 114, 114, 0.17);
|
box-shadow: 0 2px 2px var(--color-light-shadow);
|
||||||
background-color: white;
|
background-color: var(--color-background);
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
animation-fill-mode: forwards !important;
|
animation-fill-mode: forwards !important;
|
||||||
|
transition: background-color .2s;
|
||||||
|
|
||||||
&.from, &.to {
|
&.from, &.to {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -245,7 +246,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
&.slide-layers {
|
&.slide-layers {
|
||||||
--background-color: var(--color-white);
|
--background-color: var(--color-background);
|
||||||
background: black;
|
background: black;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
@ -290,7 +291,7 @@
|
|||||||
|
|
||||||
&.push-slide {
|
&.push-slide {
|
||||||
> div {
|
> div {
|
||||||
background: white;
|
background: var(--color-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
> .from {
|
> .from {
|
||||||
|
|||||||
@ -103,6 +103,7 @@ export const INITIAL_STATE: GlobalState = {
|
|||||||
isBackgroundBlurred: true,
|
isBackgroundBlurred: true,
|
||||||
animationLevel: ANIMATION_LEVEL_DEFAULT,
|
animationLevel: ANIMATION_LEVEL_DEFAULT,
|
||||||
messageSendKeyCombo: 'enter',
|
messageSendKeyCombo: 'enter',
|
||||||
|
theme: 'light',
|
||||||
shouldAutoDownloadMediaFromContacts: true,
|
shouldAutoDownloadMediaFromContacts: true,
|
||||||
shouldAutoDownloadMediaInPrivateChats: true,
|
shouldAutoDownloadMediaInPrivateChats: true,
|
||||||
shouldAutoDownloadMediaInGroups: true,
|
shouldAutoDownloadMediaInGroups: true,
|
||||||
|
|||||||
@ -4,15 +4,20 @@ import {
|
|||||||
IS_ANDROID, IS_IOS, IS_SAFARI, IS_TOUCH_ENV,
|
IS_ANDROID, IS_IOS, IS_SAFARI, IS_TOUCH_ENV,
|
||||||
} from '../../../util/environment';
|
} from '../../../util/environment';
|
||||||
import { setLanguage } from '../../../util/langProvider';
|
import { setLanguage } from '../../../util/langProvider';
|
||||||
|
import switchTheme from '../../../util/switchTheme';
|
||||||
|
|
||||||
addReducer('init', (global) => {
|
addReducer('init', (global) => {
|
||||||
const { animationLevel, messageTextSize, language } = global.settings.byKey;
|
const {
|
||||||
|
theme, animationLevel, messageTextSize, language,
|
||||||
|
} = global.settings.byKey;
|
||||||
|
|
||||||
setLanguage(language);
|
setLanguage(language);
|
||||||
|
|
||||||
document.documentElement.style.setProperty('--message-text-size', `${messageTextSize}px`);
|
document.documentElement.style.setProperty('--message-text-size', `${messageTextSize}px`);
|
||||||
|
document.body.classList.add('initial');
|
||||||
document.body.classList.add(`animation-level-${animationLevel}`);
|
document.body.classList.add(`animation-level-${animationLevel}`);
|
||||||
document.body.classList.add(IS_TOUCH_ENV ? 'is-touch-env' : 'is-pointer-env');
|
document.body.classList.add(IS_TOUCH_ENV ? 'is-touch-env' : 'is-pointer-env');
|
||||||
|
switchTheme(theme, animationLevel > 0);
|
||||||
|
|
||||||
if (IS_SAFARI) {
|
if (IS_SAFARI) {
|
||||||
document.body.classList.add('is-safari');
|
document.body.classList.add('is-safari');
|
||||||
@ -27,6 +32,10 @@ addReducer('init', (global) => {
|
|||||||
addReducer('setIsUiReady', (global, actions, payload) => {
|
addReducer('setIsUiReady', (global, actions, payload) => {
|
||||||
const { uiReadyState } = payload!;
|
const { uiReadyState } = payload!;
|
||||||
|
|
||||||
|
if (uiReadyState === 2) {
|
||||||
|
document.body.classList.remove('initial');
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...global,
|
...global,
|
||||||
uiReadyState,
|
uiReadyState,
|
||||||
|
|||||||
@ -70,9 +70,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 3.375rem;
|
height: 3.375rem;
|
||||||
padding: calc(0.75rem - var(--border-width)) calc(.9rem - var(--border-width));
|
padding: calc(0.75rem - var(--border-width)) calc(.9rem - var(--border-width));
|
||||||
border: var(--border-width) solid var(--color-borders);
|
border: var(--border-width) solid var(--color-borders-input);
|
||||||
border-radius: var(--border-radius-default);
|
border-radius: var(--border-radius-default);
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
|
background-color: var(--color-background);
|
||||||
outline: none;
|
outline: none;
|
||||||
transition: border-color 0.15s ease;
|
transition: border-color 0.15s ease;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
@ -82,7 +83,11 @@
|
|||||||
line-height: 1.25rem;
|
line-height: 1.25rem;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--color-gray);
|
border-color: var(--color-primary);
|
||||||
|
|
||||||
|
& + label {
|
||||||
|
color: var(--color-primary);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus,
|
&:focus,
|
||||||
|
|||||||
@ -64,9 +64,11 @@ $color-user-8: #faa774;
|
|||||||
--color-text-secondary-rgb: #{toRGB($color-text-secondary)};
|
--color-text-secondary-rgb: #{toRGB($color-text-secondary)};
|
||||||
--color-text-meta: #{$color-text-meta};
|
--color-text-meta: #{$color-text-meta};
|
||||||
--color-text-meta-rgb: #{toRGB($color-text-meta)};
|
--color-text-meta-rgb: #{toRGB($color-text-meta)};
|
||||||
|
--color-text-meta-colored: #{$color-text-green};
|
||||||
--color-text-green: #{$color-text-green};
|
--color-text-green: #{$color-text-green};
|
||||||
--color-text-green-rgb: #{toRGB($color-text-green)};
|
--color-text-green-rgb: #{toRGB($color-text-green)};
|
||||||
--color-borders: #{$color-borders};
|
--color-borders: #{$color-borders};
|
||||||
|
--color-borders-input: #{$color-borders};
|
||||||
--color-webpage-initial-background: #{$color-dark-gray};
|
--color-webpage-initial-background: #{$color-dark-gray};
|
||||||
--color-interactive-active: var(--color-primary);
|
--color-interactive-active: var(--color-primary);
|
||||||
--color-interactive-inactive: rgba(var(--color-text-secondary-rgb), 0.25);
|
--color-interactive-inactive: rgba(var(--color-text-secondary-rgb), 0.25);
|
||||||
@ -94,6 +96,8 @@ $color-user-8: #faa774;
|
|||||||
--color-links-darker: #{darken($color-links, 15%)};
|
--color-links-darker: #{darken($color-links, 15%)};
|
||||||
--color-links-darker-hover: #{darken($color-links, 23%)};
|
--color-links-darker-hover: #{darken($color-links, 23%)};
|
||||||
|
|
||||||
|
--color-own-links: #{$color-white};
|
||||||
|
|
||||||
--color-placeholders: #{$color-placeholders};
|
--color-placeholders: #{$color-placeholders};
|
||||||
|
|
||||||
--color-code: #4a729a;
|
--color-code: #4a729a;
|
||||||
@ -101,6 +105,9 @@ $color-user-8: #faa774;
|
|||||||
--color-code-own: #3c7940;
|
--color-code-own: #3c7940;
|
||||||
--color-code-own-bg: #{rgba($color-text-secondary, .08)};
|
--color-code-own-bg: #{rgba($color-text-secondary, .08)};
|
||||||
|
|
||||||
|
--color-accent-own: #{$color-text-green};
|
||||||
|
--color-message-meta-own: #{$color-text-green};
|
||||||
|
|
||||||
--color-reply-hover: #{blend-normal(rgba($color-text-secondary, 0.08), $color-white)};
|
--color-reply-hover: #{blend-normal(rgba($color-text-secondary, 0.08), $color-white)};
|
||||||
--color-reply-active: #{blend-normal(rgba($color-text-secondary, 0.16), $color-white)};
|
--color-reply-active: #{blend-normal(rgba($color-text-secondary, 0.16), $color-white)};
|
||||||
--color-reply-own-hover: #{blend-normal(rgba($color-text-green, 0.12), $color-light-green)};
|
--color-reply-own-hover: #{blend-normal(rgba($color-text-green, 0.12), $color-light-green)};
|
||||||
@ -123,6 +130,9 @@ $color-user-8: #faa774;
|
|||||||
--color-user-7: #{$color-user-7};
|
--color-user-7: #{$color-user-7};
|
||||||
--color-user-8: #{$color-user-8};
|
--color-user-8: #{$color-user-8};
|
||||||
|
|
||||||
|
--color-default-shadow: #72727240;
|
||||||
|
--color-light-shadow: #7272722B;
|
||||||
|
|
||||||
--border-radius-default: 0.75rem;
|
--border-radius-default: 0.75rem;
|
||||||
--border-radius-default-small: 0.625rem;
|
--border-radius-default-small: 0.625rem;
|
||||||
--border-radius-default-tiny: 0.375rem;
|
--border-radius-default-tiny: 0.375rem;
|
||||||
|
|||||||
@ -83,6 +83,10 @@ body.cursor-grabbing, body.cursor-grabbing * {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disable-animations #root * {
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.custom-scroll,
|
.custom-scroll,
|
||||||
.custom-scroll-x {
|
.custom-scroll-x {
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
|
|||||||
23
src/styles/themes.json
Normal file
23
src/styles/themes.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"--color-primary": ["#50A2E9", "#868DF5"],
|
||||||
|
"--color-background": ["#FFFFFF", "#212121"],
|
||||||
|
"--color-background-own": ["#EEFEDF", "#A45D37"],
|
||||||
|
"--color-chat-hover": ["#F4F4F5", "#2C2C2C"],
|
||||||
|
"--color-chat-active": ["#ededed", "#292929"],
|
||||||
|
"--color-text": ["#000000", "#FFFFFF"],
|
||||||
|
"--color-text-secondary": ["#707579", "#AAAAAA"],
|
||||||
|
"--color-borders": ["#DADCE0", "#100F10"],
|
||||||
|
"--color-borders-input": ["#DADCE0", "#5B5B5A"],
|
||||||
|
"--color-links": ["#52A1EF", "#868DF6"],
|
||||||
|
"--color-gray": ["#C4C9CC", "#808080"],
|
||||||
|
"--color-default-shadow": ["#72727240", "#00000099"],
|
||||||
|
"--color-light-shadow": ["#7272722B", "#00000040"],
|
||||||
|
"--color-green": ["#4DCD5E", "#868DF5"],
|
||||||
|
"--color-text-meta-colored": ["#4DCD5E", "#868DF5"],
|
||||||
|
"--color-reply-own-hover": ["#DBF4CE", "#A26947"],
|
||||||
|
"--color-reply-own-active": ["#C8EBBC", "#B0714C"],
|
||||||
|
"--color-accent-own": ["#4FAE4E", "#FFFFFF"],
|
||||||
|
"--color-message-meta-own": ["#4FAE4E", "#D9BDAD"],
|
||||||
|
"--color-own-links": ["#52A1EF", "#FFFFFF"],
|
||||||
|
"--color-code-own": ["#3C7940", "#FFFFFF"]
|
||||||
|
}
|
||||||
@ -26,6 +26,7 @@ export interface ISettings extends Record<string, any> {
|
|||||||
isBackgroundBlurred?: boolean;
|
isBackgroundBlurred?: boolean;
|
||||||
animationLevel: 0 | 1 | 2;
|
animationLevel: 0 | 1 | 2;
|
||||||
messageSendKeyCombo: 'enter' | 'ctrl-enter';
|
messageSendKeyCombo: 'enter' | 'ctrl-enter';
|
||||||
|
theme: 'light' | 'dark';
|
||||||
shouldAutoDownloadMediaFromContacts: boolean;
|
shouldAutoDownloadMediaFromContacts: boolean;
|
||||||
shouldAutoDownloadMediaInPrivateChats: boolean;
|
shouldAutoDownloadMediaInPrivateChats: boolean;
|
||||||
shouldAutoDownloadMediaInGroups: boolean;
|
shouldAutoDownloadMediaInGroups: boolean;
|
||||||
|
|||||||
85
src/util/switchTheme.ts
Normal file
85
src/util/switchTheme.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { ISettings } from '../types';
|
||||||
|
|
||||||
|
import { animateSingle } from './animation';
|
||||||
|
|
||||||
|
import themeColors from '../styles/themes.json';
|
||||||
|
|
||||||
|
type RGBAColor = {
|
||||||
|
r: number;
|
||||||
|
g: number;
|
||||||
|
b: number;
|
||||||
|
a?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
let isInitialized = false;
|
||||||
|
|
||||||
|
const HEX_COLOR_REGEX = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i;
|
||||||
|
const DURATION_MS = 200;
|
||||||
|
const ENABLE_ANIMATION_DELAY_MS = 500;
|
||||||
|
|
||||||
|
const lerp = (start: number, end: number, interpolationRatio: number) => {
|
||||||
|
return (1 - interpolationRatio) * start + interpolationRatio * end;
|
||||||
|
};
|
||||||
|
|
||||||
|
const colors = (Object.keys(themeColors) as Array<keyof typeof themeColors>).map((property) => ({
|
||||||
|
property,
|
||||||
|
colors: [hexToRgb(themeColors[property][0]), hexToRgb(themeColors[property][1])],
|
||||||
|
}));
|
||||||
|
|
||||||
|
export default (theme: ISettings['theme'], withAnimation: boolean) => {
|
||||||
|
const shouldAnimate = isInitialized && withAnimation;
|
||||||
|
const startIndex = theme === 'dark' ? 0 : 1;
|
||||||
|
const endIndex = theme === 'dark' ? 1 : 0;
|
||||||
|
const startAt = Date.now();
|
||||||
|
|
||||||
|
document.documentElement.classList.remove(`theme-${theme === 'dark' ? 'light' : 'dark'}`);
|
||||||
|
if (isInitialized) {
|
||||||
|
document.documentElement.classList.add('disable-animations');
|
||||||
|
}
|
||||||
|
document.documentElement.classList.add(`theme-${theme}`);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
document.documentElement.classList.remove('disable-animations');
|
||||||
|
}, ENABLE_ANIMATION_DELAY_MS);
|
||||||
|
|
||||||
|
isInitialized = true;
|
||||||
|
|
||||||
|
if (shouldAnimate) {
|
||||||
|
animateSingle(() => {
|
||||||
|
const t = Math.min((Date.now() - startAt) / DURATION_MS, 1);
|
||||||
|
|
||||||
|
applyColorAnimationStep(startIndex, endIndex, transition(t));
|
||||||
|
|
||||||
|
return t < 1;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
applyColorAnimationStep(startIndex, endIndex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function transition(t: number) {
|
||||||
|
return 1 - ((1 - t) ** 3.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hexToRgb(hex: string): RGBAColor {
|
||||||
|
const result = HEX_COLOR_REGEX.exec(hex)!;
|
||||||
|
|
||||||
|
return {
|
||||||
|
r: parseInt(result[1], 16),
|
||||||
|
g: parseInt(result[2], 16),
|
||||||
|
b: parseInt(result[3], 16),
|
||||||
|
a: result[4] ? parseInt(result[4], 16) : undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyColorAnimationStep(startIndex: number, endIndex: number, interpolationRatio: number = 1) {
|
||||||
|
colors.forEach(({ property, colors: propertyColors }) => {
|
||||||
|
const r = Math.round(lerp(propertyColors[startIndex].r, propertyColors[endIndex].r, interpolationRatio));
|
||||||
|
const g = Math.round(lerp(propertyColors[startIndex].g, propertyColors[endIndex].g, interpolationRatio));
|
||||||
|
const b = Math.round(lerp(propertyColors[startIndex].b, propertyColors[endIndex].b, interpolationRatio));
|
||||||
|
const a = propertyColors[startIndex].a
|
||||||
|
&& Math.round(lerp(propertyColors[startIndex].a!, propertyColors[endIndex].a!, interpolationRatio));
|
||||||
|
|
||||||
|
document.documentElement.style.setProperty(property, a ? `rgba(${r},${g},${b},${a / 255})` : `rgb(${r},${g},${b})`);
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user