Merge remote-tracking branch 'origin/develop' into react-any-emoji
This commit is contained in:
commit
cc2eafdfac
|
@ -14,12 +14,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Events: allow to repost events in event menu.
|
- Events: allow to repost events in event menu.
|
||||||
- Groups: Initial support for groups.
|
- Groups: Initial support for groups.
|
||||||
- Profile: Add RSS link to user profiles.
|
- Profile: Add RSS link to user profiles.
|
||||||
|
- Reactions: adds support for reacting to chat messages.
|
||||||
|
- Groups: initial support for groups.
|
||||||
|
- Profile: add RSS link to user profiles.
|
||||||
|
- Posts: fix posts filtering.
|
||||||
|
- Chats: reset chat message field height after sending a message.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Chats: improved display of media attachments.
|
- Chats: improved display of media attachments.
|
||||||
- ServiceWorker: switch to a network-first strategy. The "An update is available!" prompt goes away.
|
- ServiceWorker: switch to a network-first strategy. The "An update is available!" prompt goes away.
|
||||||
- Posts: increased font size of focused status in threads.
|
- Posts: increased font size of focused status in threads.
|
||||||
- Posts: let "mute conversation" be clicked from any feed, not just noficiations.
|
- Posts: let "mute conversation" be clicked from any feed, not just noficiations.
|
||||||
|
- Posts: display all emoji reactions.
|
||||||
|
- Reactions: improved UI of reactions on statuses.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Chats: media attachments rendering at the wrong size and/or causing the chat to scroll on load.
|
- Chats: media attachments rendering at the wrong size and/or causing the chat to scroll on load.
|
||||||
|
|
|
@ -32,8 +32,8 @@ const getSoapboxConfig = createSelector([
|
||||||
}
|
}
|
||||||
|
|
||||||
// If RGI reacts aren't supported, strip VS16s
|
// If RGI reacts aren't supported, strip VS16s
|
||||||
// // https://git.pleroma.social/pleroma/pleroma/-/issues/2355
|
// https://git.pleroma.social/pleroma/pleroma/-/issues/2355
|
||||||
if (!features.emojiReactsRGI) {
|
if (features.emojiReactsNonRGI) {
|
||||||
soapboxConfig.set('allowedEmoji', soapboxConfig.allowedEmoji.map(removeVS16s));
|
soapboxConfig.set('allowedEmoji', soapboxConfig.allowedEmoji.map(removeVS16s));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,7 +29,7 @@ const CopyableInput: React.FC<ICopyableInput> = ({ value }) => {
|
||||||
type='text'
|
type='text'
|
||||||
value={value}
|
value={value}
|
||||||
className='rounded-r-none rtl:rounded-l-none rtl:rounded-r-lg'
|
className='rounded-r-none rtl:rounded-l-none rtl:rounded-r-lg'
|
||||||
outerClassName='flex-grow'
|
outerClassName='grow'
|
||||||
onClick={selectInput}
|
onClick={selectInput}
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -289,8 +289,10 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HotKeys handlers={minHandlers}>
|
<HotKeys handlers={minHandlers}>
|
||||||
<div className={clsx('status__wrapper', 'status__wrapper--filtered', { focusable })} tabIndex={focusable ? 0 : undefined} ref={node}>
|
<div className={clsx('status__wrapper text-center', { focusable })} tabIndex={focusable ? 0 : undefined} ref={node}>
|
||||||
|
<Text theme='muted'>
|
||||||
<FormattedMessage id='status.filtered' defaultMessage='Filtered' />
|
<FormattedMessage id='status.filtered' defaultMessage='Filtered' />
|
||||||
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
</HotKeys>
|
</HotKeys>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,7 @@ const themes = {
|
||||||
tertiary:
|
tertiary:
|
||||||
'bg-transparent border-gray-400 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 focus:border-primary-500 text-gray-900 dark:text-gray-100 focus:ring-primary-500',
|
'bg-transparent border-gray-400 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 focus:border-primary-500 text-gray-900 dark:text-gray-100 focus:ring-primary-500',
|
||||||
accent: 'border-transparent bg-secondary-500 hover:bg-secondary-400 focus:bg-secondary-500 text-gray-100 focus:ring-secondary-300',
|
accent: 'border-transparent bg-secondary-500 hover:bg-secondary-400 focus:bg-secondary-500 text-gray-100 focus:ring-secondary-300',
|
||||||
danger: 'border-transparent bg-danger-100 dark:bg-danger-900 text-danger-600 dark:text-danger-200 hover:bg-danger-600 hover:text-gray-100 dark:hover:text-gray-100 dark:hover:bg-danger-500 focus:bg-danger-800 dark:focus:bg-danger-600',
|
danger: 'border-transparent bg-danger-100 dark:bg-danger-900 text-danger-600 dark:text-danger-200 hover:bg-danger-600 hover:text-gray-100 dark:hover:text-gray-100 dark:hover:bg-danger-500 focus:bg-danger-800 focus:text-gray-200 dark:focus:bg-danger-600 dark:focus:text-gray-100',
|
||||||
transparent: 'border-transparent text-gray-800 backdrop-blur-sm bg-white/75 hover:bg-white/80',
|
transparent: 'border-transparent text-gray-800 backdrop-blur-sm bg-white/75 hover:bg-white/80',
|
||||||
outline: 'border-gray-100 border-2 bg-transparent text-gray-100 hover:bg-white/10',
|
outline: 'border-gray-100 border-2 bg-transparent text-gray-100 hover:bg-white/10',
|
||||||
muted: 'border border-solid bg-transparent border-gray-400 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 focus:border-primary-500 text-gray-900 dark:text-gray-100 focus:ring-primary-500',
|
muted: 'border border-solid bg-transparent border-gray-400 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 focus:border-primary-500 text-gray-900 dark:text-gray-100 focus:ring-primary-500',
|
||||||
|
|
|
@ -6,8 +6,7 @@ import { makeGetStatus } from 'soapbox/selectors';
|
||||||
|
|
||||||
interface IStatusContainer extends Omit<IStatus, 'status'> {
|
interface IStatusContainer extends Omit<IStatus, 'status'> {
|
||||||
id: string,
|
id: string,
|
||||||
/** @deprecated Unused. */
|
contextType?: string,
|
||||||
contextType?: any,
|
|
||||||
/** @deprecated Unused. */
|
/** @deprecated Unused. */
|
||||||
otherAccounts?: any,
|
otherAccounts?: any,
|
||||||
/** @deprecated Unused. */
|
/** @deprecated Unused. */
|
||||||
|
@ -21,10 +20,10 @@ interface IStatusContainer extends Omit<IStatus, 'status'> {
|
||||||
* @deprecated Use the Status component directly.
|
* @deprecated Use the Status component directly.
|
||||||
*/
|
*/
|
||||||
const StatusContainer: React.FC<IStatusContainer> = (props) => {
|
const StatusContainer: React.FC<IStatusContainer> = (props) => {
|
||||||
const { id, ...rest } = props;
|
const { id, contextType, ...rest } = props;
|
||||||
|
|
||||||
const getStatus = useCallback(makeGetStatus(), []);
|
const getStatus = useCallback(makeGetStatus(), []);
|
||||||
const status = useAppSelector(state => getStatus(state, { id }));
|
const status = useAppSelector(state => getStatus(state, { id, contextType }));
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
return <Status status={status} {...rest} />;
|
return <Status status={status} {...rest} />;
|
||||||
|
|
|
@ -4,9 +4,8 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { expandUserIndex, fetchUserIndex, setUserIndexQuery } from 'soapbox/actions/admin';
|
import { expandUserIndex, fetchUserIndex, setUserIndexQuery } from 'soapbox/actions/admin';
|
||||||
import ScrollableList from 'soapbox/components/scrollable-list';
|
import ScrollableList from 'soapbox/components/scrollable-list';
|
||||||
import { Column } from 'soapbox/components/ui';
|
import { Column, Input } from 'soapbox/components/ui';
|
||||||
import AccountContainer from 'soapbox/containers/account-container';
|
import AccountContainer from 'soapbox/containers/account-container';
|
||||||
import { SimpleForm, TextInput } from 'soapbox/features/forms';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -22,7 +21,7 @@ const UserIndex: React.FC = () => {
|
||||||
const { isLoading, items, total, query, next } = useAppSelector((state) => state.admin_user_index);
|
const { isLoading, items, total, query, next } = useAppSelector((state) => state.admin_user_index);
|
||||||
|
|
||||||
const handleLoadMore = () => {
|
const handleLoadMore = () => {
|
||||||
dispatch(expandUserIndex());
|
if (!isLoading) dispatch(expandUserIndex());
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateQuery = useCallback(debounce(() => {
|
const updateQuery = useCallback(debounce(() => {
|
||||||
|
@ -31,25 +30,25 @@ const UserIndex: React.FC = () => {
|
||||||
|
|
||||||
const handleQueryChange: React.ChangeEventHandler<HTMLInputElement> = e => {
|
const handleQueryChange: React.ChangeEventHandler<HTMLInputElement> = e => {
|
||||||
dispatch(setUserIndexQuery(e.target.value));
|
dispatch(setUserIndexQuery(e.target.value));
|
||||||
|
updateQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateQuery();
|
updateQuery();
|
||||||
}, [query]);
|
}, []);
|
||||||
|
|
||||||
const hasMore = items.count() < total && next !== null;
|
|
||||||
|
const hasMore = items.count() < total && !!next;
|
||||||
|
|
||||||
const showLoading = isLoading && items.isEmpty();
|
const showLoading = isLoading && items.isEmpty();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column label={intl.formatMessage(messages.heading)}>
|
<Column label={intl.formatMessage(messages.heading)}>
|
||||||
<SimpleForm style={{ paddingBottom: 0 }}>
|
<Input
|
||||||
<TextInput
|
|
||||||
value={query}
|
value={query}
|
||||||
onChange={handleQueryChange}
|
onChange={handleQueryChange}
|
||||||
placeholder={intl.formatMessage(messages.searchPlaceholder)}
|
placeholder={intl.formatMessage(messages.searchPlaceholder)}
|
||||||
/>
|
/>
|
||||||
</SimpleForm>
|
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
scrollKey='user-index'
|
scrollKey='user-index'
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
|
|
|
@ -42,6 +42,7 @@ interface IChatComposer extends Pick<React.TextareaHTMLAttributes<HTMLTextAreaEl
|
||||||
errorMessage: string | undefined
|
errorMessage: string | undefined
|
||||||
onSelectFile: (files: FileList, intl: IntlShape) => void
|
onSelectFile: (files: FileList, intl: IntlShape) => void
|
||||||
resetFileKey: number | null
|
resetFileKey: number | null
|
||||||
|
resetContentKey: number | null
|
||||||
attachments?: Attachment[]
|
attachments?: Attachment[]
|
||||||
onDeleteAttachment?: () => void
|
onDeleteAttachment?: () => void
|
||||||
isUploading?: boolean
|
isUploading?: boolean
|
||||||
|
@ -58,6 +59,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
|
||||||
disabled = false,
|
disabled = false,
|
||||||
onSelectFile,
|
onSelectFile,
|
||||||
resetFileKey,
|
resetFileKey,
|
||||||
|
resetContentKey,
|
||||||
onPaste,
|
onPaste,
|
||||||
attachments = [],
|
attachments = [],
|
||||||
onDeleteAttachment,
|
onDeleteAttachment,
|
||||||
|
@ -179,6 +181,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
|
||||||
<Stack grow>
|
<Stack grow>
|
||||||
<Combobox onSelect={onSelectComboboxOption}>
|
<Combobox onSelect={onSelectComboboxOption}>
|
||||||
<ComboboxInput
|
<ComboboxInput
|
||||||
|
key={resetContentKey}
|
||||||
as={ChatTextarea}
|
as={ChatTextarea}
|
||||||
autoFocus
|
autoFocus
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|
|
@ -54,6 +54,7 @@ const Chat: React.FC<ChatInterface> = ({ chat, inputRef, className }) => {
|
||||||
const [attachment, setAttachment] = useState<any>(undefined);
|
const [attachment, setAttachment] = useState<any>(undefined);
|
||||||
const [isUploading, setIsUploading] = useState(false);
|
const [isUploading, setIsUploading] = useState(false);
|
||||||
const [uploadProgress, setUploadProgress] = useState(0);
|
const [uploadProgress, setUploadProgress] = useState(0);
|
||||||
|
const [resetContentKey, setResetContentKey] = useState<number>(fileKeyGen());
|
||||||
const [resetFileKey, setResetFileKey] = useState<number>(fileKeyGen());
|
const [resetFileKey, setResetFileKey] = useState<number>(fileKeyGen());
|
||||||
const [errorMessage, setErrorMessage] = useState<string>();
|
const [errorMessage, setErrorMessage] = useState<string>();
|
||||||
|
|
||||||
|
@ -83,6 +84,7 @@ const Chat: React.FC<ChatInterface> = ({ chat, inputRef, className }) => {
|
||||||
setIsUploading(false);
|
setIsUploading(false);
|
||||||
setUploadProgress(0);
|
setUploadProgress(0);
|
||||||
setResetFileKey(fileKeyGen());
|
setResetFileKey(fileKeyGen());
|
||||||
|
setResetContentKey(fileKeyGen());
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendMessage = () => {
|
const sendMessage = () => {
|
||||||
|
@ -171,6 +173,7 @@ const Chat: React.FC<ChatInterface> = ({ chat, inputRef, className }) => {
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}
|
||||||
onSelectFile={handleFiles}
|
onSelectFile={handleFiles}
|
||||||
resetFileKey={resetFileKey}
|
resetFileKey={resetFileKey}
|
||||||
|
resetContentKey={resetContentKey}
|
||||||
onPaste={handlePaste}
|
onPaste={handlePaste}
|
||||||
attachments={attachment ? [attachment] : []}
|
attachments={attachment ? [attachment] : []}
|
||||||
onDeleteAttachment={handleRemoveFile}
|
onDeleteAttachment={handleRemoveFile}
|
||||||
|
|
|
@ -242,7 +242,10 @@ const PrivacyDropdown: React.FC<IPrivacyDropdown> = ({
|
||||||
<div className={clsx('privacy-dropdown', placement, { active: open })} onKeyDown={handleKeyDown} ref={node}>
|
<div className={clsx('privacy-dropdown', placement, { active: open })} onKeyDown={handleKeyDown} ref={node}>
|
||||||
<div className={clsx('privacy-dropdown__value', { active: valueOption && options.indexOf(valueOption) === 0 })}>
|
<div className={clsx('privacy-dropdown__value', { active: valueOption && options.indexOf(valueOption) === 0 })}>
|
||||||
<IconButton
|
<IconButton
|
||||||
className='text-gray-600 hover:text-gray-700 dark:hover:text-gray-500'
|
className={clsx({
|
||||||
|
'text-gray-600 hover:text-gray-700 dark:hover:text-gray-500': !open,
|
||||||
|
'text-primary-500 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-400': open,
|
||||||
|
})}
|
||||||
src={valueOption?.icon}
|
src={valueOption?.icon}
|
||||||
title={intl.formatMessage(messages.change_privacy)}
|
title={intl.formatMessage(messages.change_privacy)}
|
||||||
onClick={handleToggle}
|
onClick={handleToggle}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import AttachmentThumbs from 'soapbox/components/attachment-thumbs';
|
import AttachmentThumbs from 'soapbox/components/attachment-thumbs';
|
||||||
|
@ -8,12 +9,13 @@ import { isRtl } from 'soapbox/rtl';
|
||||||
import type { Status } from 'soapbox/types/entities';
|
import type { Status } from 'soapbox/types/entities';
|
||||||
|
|
||||||
interface IReplyIndicator {
|
interface IReplyIndicator {
|
||||||
|
className?: string,
|
||||||
status?: Status,
|
status?: Status,
|
||||||
onCancel?: () => void,
|
onCancel?: () => void,
|
||||||
hideActions: boolean,
|
hideActions: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReplyIndicator: React.FC<IReplyIndicator> = ({ status, hideActions, onCancel }) => {
|
const ReplyIndicator: React.FC<IReplyIndicator> = ({ className, status, hideActions, onCancel }) => {
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
onCancel!();
|
onCancel!();
|
||||||
};
|
};
|
||||||
|
@ -33,7 +35,7 @@ const ReplyIndicator: React.FC<IReplyIndicator> = ({ status, hideActions, onCanc
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack space={2} className='rounded-lg bg-gray-100 p-4 dark:bg-gray-800'>
|
<Stack space={2} className={clsx('rounded-lg bg-gray-100 p-4 dark:bg-gray-800', className)}>
|
||||||
<AccountContainer
|
<AccountContainer
|
||||||
{...actions}
|
{...actions}
|
||||||
id={status.getIn(['account', 'id']) as string}
|
id={status.getIn(['account', 'id']) as string}
|
||||||
|
|
|
@ -152,14 +152,14 @@ const ProfileField: StreamfieldComponent<AccountCredentialsField> = ({ value, on
|
||||||
<HStack space={2} grow>
|
<HStack space={2} grow>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
outerClassName='w-2/5 flex-grow'
|
outerClassName='w-2/5 grow'
|
||||||
value={value.name}
|
value={value.name}
|
||||||
onChange={handleChange('name')}
|
onChange={handleChange('name')}
|
||||||
placeholder={intl.formatMessage(messages.metaFieldLabel)}
|
placeholder={intl.formatMessage(messages.metaFieldLabel)}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
outerClassName='w-3/5 flex-grow'
|
outerClassName='w-3/5 grow'
|
||||||
value={value.value}
|
value={value.value}
|
||||||
onChange={handleChange('value')}
|
onChange={handleChange('value')}
|
||||||
placeholder={intl.formatMessage(messages.metaFieldContent)}
|
placeholder={intl.formatMessage(messages.metaFieldContent)}
|
||||||
|
|
|
@ -2,13 +2,9 @@ import React, { useEffect, useState } from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { fetchFilters, createFilter, deleteFilter } from 'soapbox/actions/filters';
|
import { fetchFilters, createFilter, deleteFilter } from 'soapbox/actions/filters';
|
||||||
import Icon from 'soapbox/components/icon';
|
import List, { ListItem } from 'soapbox/components/list';
|
||||||
import ScrollableList from 'soapbox/components/scrollable-list';
|
import ScrollableList from 'soapbox/components/scrollable-list';
|
||||||
import { Button, CardHeader, CardTitle, Column, Form, FormActions, FormGroup, Input, Text } from 'soapbox/components/ui';
|
import { Button, CardHeader, CardTitle, Column, Form, FormActions, FormGroup, HStack, IconButton, Input, Stack, Text, Toggle } from 'soapbox/components/ui';
|
||||||
import {
|
|
||||||
FieldsGroup,
|
|
||||||
Checkbox,
|
|
||||||
} from 'soapbox/features/forms';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||||
import toast from 'soapbox/toast';
|
import toast from 'soapbox/toast';
|
||||||
|
|
||||||
|
@ -33,6 +29,13 @@ const messages = defineMessages({
|
||||||
delete: { id: 'column.filters.delete', defaultMessage: 'Delete' },
|
delete: { id: 'column.filters.delete', defaultMessage: 'Delete' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const contexts = {
|
||||||
|
home: messages.home_timeline,
|
||||||
|
public: messages.public_timeline,
|
||||||
|
notifications: messages.notifications,
|
||||||
|
thread: messages.conversations,
|
||||||
|
};
|
||||||
|
|
||||||
// const expirations = {
|
// const expirations = {
|
||||||
// null: 'Never',
|
// null: 'Never',
|
||||||
// // 3600: '30 minutes',
|
// // 3600: '30 minutes',
|
||||||
|
@ -85,8 +88,8 @@ const Filters = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFilterDelete: React.MouseEventHandler<HTMLDivElement> = e => {
|
const handleFilterDelete = (id: string) => () => {
|
||||||
dispatch(deleteFilter(e.currentTarget.dataset.value!)).then(() => {
|
dispatch(deleteFilter(id)).then(() => {
|
||||||
return dispatch(fetchFilters());
|
return dispatch(fetchFilters());
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
toast.error(intl.formatMessage(messages.delete_error));
|
toast.error(intl.formatMessage(messages.delete_error));
|
||||||
|
@ -121,58 +124,68 @@ const Filters = () => {
|
||||||
/>
|
/>
|
||||||
</FormGroup> */}
|
</FormGroup> */}
|
||||||
|
|
||||||
<FieldsGroup>
|
<Stack>
|
||||||
<Text tag='label'>
|
<Text size='sm' weight='medium'>
|
||||||
<FormattedMessage id='filters.context_header' defaultMessage='Filter contexts' />
|
<FormattedMessage id='filters.context_header' defaultMessage='Filter contexts' />
|
||||||
</Text>
|
</Text>
|
||||||
<Text theme='muted' size='xs'>
|
<Text size='xs' theme='muted'>
|
||||||
<FormattedMessage id='filters.context_hint' defaultMessage='One or multiple contexts where the filter should apply' />
|
<FormattedMessage id='filters.context_hint' defaultMessage='One or multiple contexts where the filter should apply' />
|
||||||
</Text>
|
</Text>
|
||||||
<div className='two-col'>
|
</Stack>
|
||||||
<Checkbox
|
|
||||||
label={intl.formatMessage(messages.home_timeline)}
|
<List>
|
||||||
|
<ListItem label={intl.formatMessage(messages.home_timeline)}>
|
||||||
|
<Toggle
|
||||||
name='home_timeline'
|
name='home_timeline'
|
||||||
checked={homeTimeline}
|
checked={homeTimeline}
|
||||||
onChange={({ target }) => setHomeTimeline(target.checked)}
|
onChange={({ target }) => setHomeTimeline(target.checked)}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
</ListItem>
|
||||||
label={intl.formatMessage(messages.public_timeline)}
|
<ListItem label={intl.formatMessage(messages.public_timeline)}>
|
||||||
|
<Toggle
|
||||||
name='public_timeline'
|
name='public_timeline'
|
||||||
checked={publicTimeline}
|
checked={publicTimeline}
|
||||||
onChange={({ target }) => setPublicTimeline(target.checked)}
|
onChange={({ target }) => setPublicTimeline(target.checked)}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
</ListItem>
|
||||||
label={intl.formatMessage(messages.notifications)}
|
<ListItem label={intl.formatMessage(messages.notifications)}>
|
||||||
|
<Toggle
|
||||||
name='notifications'
|
name='notifications'
|
||||||
checked={notifications}
|
checked={notifications}
|
||||||
onChange={({ target }) => setNotifications(target.checked)}
|
onChange={({ target }) => setNotifications(target.checked)}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
</ListItem>
|
||||||
label={intl.formatMessage(messages.conversations)}
|
<ListItem label={intl.formatMessage(messages.conversations)}>
|
||||||
|
<Toggle
|
||||||
name='conversations'
|
name='conversations'
|
||||||
checked={conversations}
|
checked={conversations}
|
||||||
onChange={({ target }) => setConversations(target.checked)}
|
onChange={({ target }) => setConversations(target.checked)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
|
||||||
</FieldsGroup>
|
<List>
|
||||||
|
<ListItem
|
||||||
<FieldsGroup>
|
|
||||||
<Checkbox
|
|
||||||
label={intl.formatMessage(messages.drop_header)}
|
label={intl.formatMessage(messages.drop_header)}
|
||||||
hint={intl.formatMessage(messages.drop_hint)}
|
hint={intl.formatMessage(messages.drop_hint)}
|
||||||
|
>
|
||||||
|
<Toggle
|
||||||
name='irreversible'
|
name='irreversible'
|
||||||
checked={irreversible}
|
checked={irreversible}
|
||||||
onChange={({ target }) => setIrreversible(target.checked)}
|
onChange={({ target }) => setIrreversible(target.checked)}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
</ListItem>
|
||||||
|
<ListItem
|
||||||
label={intl.formatMessage(messages.whole_word_header)}
|
label={intl.formatMessage(messages.whole_word_header)}
|
||||||
hint={intl.formatMessage(messages.whole_word_hint)}
|
hint={intl.formatMessage(messages.whole_word_hint)}
|
||||||
|
>
|
||||||
|
<Toggle
|
||||||
name='whole_word'
|
name='whole_word'
|
||||||
checked={wholeWord}
|
checked={wholeWord}
|
||||||
onChange={({ target }) => setWholeWord(target.checked)}
|
onChange={({ target }) => setWholeWord(target.checked)}
|
||||||
/>
|
/>
|
||||||
</FieldsGroup>
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
|
||||||
<FormActions>
|
<FormActions>
|
||||||
<Button type='submit' theme='primary'>{intl.formatMessage(messages.add_new)}</Button>
|
<Button type='submit' theme='primary'>{intl.formatMessage(messages.add_new)}</Button>
|
||||||
|
@ -186,40 +199,41 @@ const Filters = () => {
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
scrollKey='filters'
|
scrollKey='filters'
|
||||||
emptyMessage={emptyMessage}
|
emptyMessage={emptyMessage}
|
||||||
|
itemClassName='pb-4 last:pb-0'
|
||||||
>
|
>
|
||||||
{filters.map((filter, i) => (
|
{filters.map((filter, i) => (
|
||||||
<div key={i} className='filter__container'>
|
<HStack space={1} justifyContent='between'>
|
||||||
<div className='filter__details'>
|
<Stack space={1}>
|
||||||
<div className='filter__phrase'>
|
<Text weight='medium'>
|
||||||
<span className='filter__list-label'><FormattedMessage id='filters.filters_list_phrase_label' defaultMessage='Keyword or phrase:' /></span>
|
<FormattedMessage id='filters.filters_list_phrase_label' defaultMessage='Keyword or phrase:' />
|
||||||
<span className='filter__list-value'>{filter.phrase}</span>
|
{' '}
|
||||||
</div>
|
<Text theme='muted' tag='span'>{filter.phrase}</Text>
|
||||||
<div className='filter__contexts'>
|
</Text>
|
||||||
<span className='filter__list-label'><FormattedMessage id='filters.filters_list_context_label' defaultMessage='Filter contexts:' /></span>
|
<Text weight='medium'>
|
||||||
<span className='filter__list-value'>
|
<FormattedMessage id='filters.filters_list_context_label' defaultMessage='Filter contexts:' />
|
||||||
{filter.context.map((context, i) => (
|
{' '}
|
||||||
<span key={i} className='context'>{context}</span>
|
<Text theme='muted' tag='span'>{filter.context.map(context => contexts[context] ? intl.formatMessage(contexts[context]) : context).join(', ')}</Text>
|
||||||
))}
|
</Text>
|
||||||
</span>
|
<HStack space={4}>
|
||||||
</div>
|
<Text weight='medium'>
|
||||||
<div className='filter__details'>
|
|
||||||
<span className='filter__list-label'><FormattedMessage id='filters.filters_list_details_label' defaultMessage='Filter settings:' /></span>
|
|
||||||
<span className='filter__list-value'>
|
|
||||||
{filter.irreversible ?
|
{filter.irreversible ?
|
||||||
<span><FormattedMessage id='filters.filters_list_drop' defaultMessage='Drop' /></span> :
|
<FormattedMessage id='filters.filters_list_drop' defaultMessage='Drop' /> :
|
||||||
<span><FormattedMessage id='filters.filters_list_hide' defaultMessage='Hide' /></span>
|
<FormattedMessage id='filters.filters_list_hide' defaultMessage='Hide' />}
|
||||||
}
|
</Text>
|
||||||
{filter.whole_word &&
|
{filter.whole_word && (
|
||||||
<span><FormattedMessage id='filters.filters_list_whole-word' defaultMessage='Whole word' /></span>
|
<Text weight='medium'>
|
||||||
}
|
<FormattedMessage id='filters.filters_list_whole-word' defaultMessage='Whole word' />
|
||||||
</span>
|
</Text>
|
||||||
</div>
|
)}
|
||||||
</div>
|
</HStack>
|
||||||
<div className='filter__delete' role='button' tabIndex={0} onClick={handleFilterDelete} data-value={filter.id} aria-label={intl.formatMessage(messages.delete)}>
|
</Stack>
|
||||||
<Icon className='filter__delete-icon' src={require('@tabler/icons/x.svg')} />
|
<IconButton
|
||||||
<span className='filter__delete-label'><FormattedMessage id='filters.filters_list_delete' defaultMessage='Delete' /></span>
|
iconClassName='h-5 w-5 text-gray-700 dark:text-gray-600 hover:text-gray-800 dark:hover:text-gray-500'
|
||||||
</div>
|
src={require('@tabler/icons/trash.svg')}
|
||||||
</div>
|
onClick={handleFilterDelete(filter.id)}
|
||||||
|
title={intl.formatMessage(messages.delete)}
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
))}
|
))}
|
||||||
</ScrollableList>
|
</ScrollableList>
|
||||||
</Column>
|
</Column>
|
||||||
|
|
|
@ -103,71 +103,6 @@ export const SimpleInput: React.FC<ISimpleInput> = (props) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ISimpleTextarea {
|
|
||||||
label?: React.ReactNode,
|
|
||||||
hint?: React.ReactNode,
|
|
||||||
value?: string,
|
|
||||||
onChange?: React.ChangeEventHandler<HTMLTextAreaElement>,
|
|
||||||
rows?: number,
|
|
||||||
name?: string,
|
|
||||||
maxLength?: number,
|
|
||||||
required?: boolean,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SimpleTextarea: React.FC<ISimpleTextarea> = (props) => {
|
|
||||||
const { hint, label, ...rest } = props;
|
|
||||||
const Input = label ? LabelTextarea : 'textarea';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<InputContainer {...props}>
|
|
||||||
<Input {...rest} />
|
|
||||||
</InputContainer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface ISimpleForm {
|
|
||||||
className?: string,
|
|
||||||
onSubmit?: React.FormEventHandler,
|
|
||||||
acceptCharset?: string,
|
|
||||||
style?: React.CSSProperties,
|
|
||||||
children: React.ReactNode,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SimpleForm: React.FC<ISimpleForm> = (props) => {
|
|
||||||
const {
|
|
||||||
className,
|
|
||||||
children,
|
|
||||||
onSubmit = () => {},
|
|
||||||
acceptCharset = 'UTF-8',
|
|
||||||
...rest
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const handleSubmit: React.FormEventHandler = e => {
|
|
||||||
onSubmit(e);
|
|
||||||
e.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form
|
|
||||||
className={clsx('simple_form', className)}
|
|
||||||
method='post'
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
acceptCharset={acceptCharset}
|
|
||||||
{...rest}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface IFieldsGroup {
|
|
||||||
children: React.ReactNode,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const FieldsGroup: React.FC<IFieldsGroup> = ({ children }) => (
|
|
||||||
<div className='fields-group'>{children}</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
interface ICheckbox {
|
interface ICheckbox {
|
||||||
label?: React.ReactNode,
|
label?: React.ReactNode,
|
||||||
hint?: React.ReactNode,
|
hint?: React.ReactNode,
|
||||||
|
|
|
@ -36,7 +36,7 @@ const ListForm = () => {
|
||||||
<Form onSubmit={handleSubmit}>
|
<Form onSubmit={handleSubmit}>
|
||||||
<HStack space={2}>
|
<HStack space={2}>
|
||||||
<Input
|
<Input
|
||||||
outerClassName='flex-grow'
|
outerClassName='grow'
|
||||||
type='text'
|
type='text'
|
||||||
value={value}
|
value={value}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
import Icon from 'soapbox/components/icon';
|
|
||||||
|
|
||||||
interface IClearColumnButton {
|
|
||||||
onClick: React.MouseEventHandler<HTMLButtonElement>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClearColumnButton: React.FC<IClearColumnButton> = ({ onClick }) => (
|
|
||||||
<button className='text-btn column-header__setting-btn' tabIndex={0} onClick={onClick}>
|
|
||||||
<Icon src={require('@tabler/icons/eraser.svg')} />
|
|
||||||
{' '}
|
|
||||||
<FormattedMessage id='notifications.clear' defaultMessage='Clear notifications' />
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default ClearColumnButton;
|
|
|
@ -329,6 +329,7 @@ const Notification: React.FC<INotificaton> = (props) => {
|
||||||
onMoveDown={handleMoveDown}
|
onMoveDown={handleMoveDown}
|
||||||
onMoveUp={handleMoveUp}
|
onMoveUp={handleMoveUp}
|
||||||
avatarSize={avatarSize}
|
avatarSize={avatarSize}
|
||||||
|
contextType='notifications'
|
||||||
/>
|
/>
|
||||||
) : null;
|
) : null;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -78,7 +78,7 @@ const PlaceholderMediaGallery: React.FC<IPlaceholderMediaGallery> = ({ media, de
|
||||||
const float = dimensions.float as any || 'left';
|
const float = dimensions.float as any || 'left';
|
||||||
const position = dimensions.pos as any || 'relative';
|
const position = dimensions.pos as any || 'relative';
|
||||||
|
|
||||||
return <div key={i} className='media-gallery__item' style={{ position, float, left, top, right, bottom, height, width }} />;
|
return <div key={i} className='media-gallery__item animate-pulse bg-primary-200' style={{ position, float, left, top, right, bottom, height, width }} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const sizeData = getSizeData(media.size);
|
const sizeData = getSizeData(media.size);
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
|
||||||
|
|
||||||
import { getSettings, changeSettingImmediate } from 'soapbox/actions/settings';
|
|
||||||
import List, { ListItem } from 'soapbox/components/list';
|
|
||||||
import { Card, CardBody, CardHeader, CardTitle } from 'soapbox/components/ui';
|
|
||||||
import { SimpleForm, SelectDropdown } from 'soapbox/features/forms';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
mediaDisplay: { id: 'preferences.fields.media_display_label', defaultMessage: 'Media display' },
|
|
||||||
display_media_default: { id: 'preferences.fields.display_media.default', defaultMessage: 'Hide media marked as sensitive' },
|
|
||||||
display_media_hide_all: { id: 'preferences.fields.display_media.hide_all', defaultMessage: 'Always hide media' },
|
|
||||||
display_media_show_all: { id: 'preferences.fields.display_media.show_all', defaultMessage: 'Always show media' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const MediaDisplay = () => {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const intl = useIntl();
|
|
||||||
|
|
||||||
const settings = useAppSelector((state) => getSettings(state));
|
|
||||||
|
|
||||||
const displayMediaOptions = {
|
|
||||||
default: intl.formatMessage(messages.display_media_default),
|
|
||||||
hide_all: intl.formatMessage(messages.display_media_hide_all),
|
|
||||||
show_all: intl.formatMessage(messages.display_media_show_all),
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSelectChange: (path: string[]) => React.ChangeEventHandler<HTMLSelectElement> = path => {
|
|
||||||
return e => {
|
|
||||||
dispatch(changeSettingImmediate(path, e.target.value));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card variant='rounded'>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle title={intl.formatMessage(messages.mediaDisplay)} />
|
|
||||||
</CardHeader>
|
|
||||||
|
|
||||||
<CardBody>
|
|
||||||
<SimpleForm className='space-y-3 p-0'>
|
|
||||||
<List>
|
|
||||||
<ListItem label={intl.formatMessage(messages.mediaDisplay)}>
|
|
||||||
<SelectDropdown
|
|
||||||
items={displayMediaOptions}
|
|
||||||
defaultValue={settings.get('displayMedia') as string}
|
|
||||||
onChange={onSelectChange(['displayMedia'])}
|
|
||||||
/>
|
|
||||||
</ListItem>
|
|
||||||
</List>
|
|
||||||
</SimpleForm>
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MediaDisplay;
|
|
|
@ -25,21 +25,21 @@ const CryptoAddressInput: StreamfieldComponent<CryptoAddress> = ({ value, onChan
|
||||||
<HStack space={2} grow>
|
<HStack space={2} grow>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
outerClassName='w-1/6 flex-grow'
|
outerClassName='w-1/6 grow'
|
||||||
value={value.ticker}
|
value={value.ticker}
|
||||||
onChange={handleChange('ticker')}
|
onChange={handleChange('ticker')}
|
||||||
placeholder={intl.formatMessage(messages.ticker)}
|
placeholder={intl.formatMessage(messages.ticker)}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
outerClassName='w-3/6 flex-grow'
|
outerClassName='w-3/6 grow'
|
||||||
value={value.address}
|
value={value.address}
|
||||||
onChange={handleChange('address')}
|
onChange={handleChange('address')}
|
||||||
placeholder={intl.formatMessage(messages.address)}
|
placeholder={intl.formatMessage(messages.address)}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
outerClassName='w-2/6 flex-grow'
|
outerClassName='w-2/6 grow'
|
||||||
value={value.note}
|
value={value.note}
|
||||||
onChange={handleChange('note')}
|
onChange={handleChange('note')}
|
||||||
placeholder={intl.formatMessage(messages.note)}
|
placeholder={intl.formatMessage(messages.note)}
|
||||||
|
|
|
@ -24,14 +24,14 @@ const PromoPanelInput: StreamfieldComponent<FooterItem> = ({ value, onChange })
|
||||||
<HStack space={2} grow>
|
<HStack space={2} grow>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
outerClassName='w-full flex-grow'
|
outerClassName='w-full grow'
|
||||||
placeholder={intl.formatMessage(messages.label)}
|
placeholder={intl.formatMessage(messages.label)}
|
||||||
value={value.title}
|
value={value.title}
|
||||||
onChange={handleChange('title')}
|
onChange={handleChange('title')}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
outerClassName='w-full flex-grow'
|
outerClassName='w-full grow'
|
||||||
placeholder={intl.formatMessage(messages.url)}
|
placeholder={intl.formatMessage(messages.url)}
|
||||||
value={value.url}
|
value={value.url}
|
||||||
onChange={handleChange('url')}
|
onChange={handleChange('url')}
|
||||||
|
|
|
@ -36,14 +36,14 @@ const PromoPanelInput: StreamfieldComponent<PromoPanelItem> = ({ value, onChange
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
outerClassName='w-full flex-grow'
|
outerClassName='w-full grow'
|
||||||
placeholder={intl.formatMessage(messages.label)}
|
placeholder={intl.formatMessage(messages.label)}
|
||||||
value={value.text}
|
value={value.text}
|
||||||
onChange={handleChange('text')}
|
onChange={handleChange('text')}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
outerClassName='w-full flex-grow'
|
outerClassName='w-full grow'
|
||||||
placeholder={intl.formatMessage(messages.url)}
|
placeholder={intl.formatMessage(messages.url)}
|
||||||
value={value.url}
|
value={value.url}
|
||||||
onChange={handleChange('url')}
|
onChange={handleChange('url')}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import classnames from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ const Card: React.FC<ICard> = ({
|
||||||
|
|
||||||
const interactive = card.type !== 'link';
|
const interactive = card.type !== 'link';
|
||||||
horizontal = typeof horizontal === 'boolean' ? horizontal : interactive || embedded;
|
horizontal = typeof horizontal === 'boolean' ? horizontal : interactive || embedded;
|
||||||
const className = classnames('status-card', { horizontal, compact, interactive }, `status-card--${card.type}`);
|
const className = clsx('status-card', { horizontal, compact, interactive }, `status-card--${card.type}`);
|
||||||
const ratio = getRatio(card);
|
const ratio = getRatio(card);
|
||||||
const height = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
|
const height = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ const Card: React.FC<ICard> = ({
|
||||||
);
|
);
|
||||||
} else if (card.image) {
|
} else if (card.image) {
|
||||||
embed = (
|
embed = (
|
||||||
<div className={classnames(
|
<div className={clsx(
|
||||||
'status-card__image',
|
'status-card__image',
|
||||||
'w-full flex-none rounded-l md:h-auto md:w-auto md:flex-auto',
|
'w-full flex-none rounded-l md:h-auto md:w-auto md:flex-auto',
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { useAppSelector } from 'soapbox/hooks';
|
||||||
|
|
||||||
interface IThreadStatus {
|
interface IThreadStatus {
|
||||||
id: string,
|
id: string,
|
||||||
|
contextType?: string,
|
||||||
focusedStatusId: string,
|
focusedStatusId: string,
|
||||||
onMoveUp: (id: string) => void,
|
onMoveUp: (id: string) => void,
|
||||||
onMoveDown: (id: string) => void,
|
onMoveDown: (id: string) => void,
|
||||||
|
|
|
@ -361,6 +361,7 @@ const Thread: React.FC<IThread> = (props) => {
|
||||||
focusedStatusId={status!.id}
|
focusedStatusId={status!.id}
|
||||||
onMoveUp={handleMoveUp}
|
onMoveUp={handleMoveUp}
|
||||||
onMoveDown={handleMoveDown}
|
onMoveDown={handleMoveDown}
|
||||||
|
contextType='thread'
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,9 +4,8 @@ import { FormattedMessage } from 'react-intl';
|
||||||
import { spring } from 'react-motion';
|
import { spring } from 'react-motion';
|
||||||
|
|
||||||
import Icon from 'soapbox/components/icon';
|
import Icon from 'soapbox/components/icon';
|
||||||
import StatusContent from 'soapbox/components/status-content';
|
import { HStack } from 'soapbox/components/ui';
|
||||||
import { HStack, Stack } from 'soapbox/components/ui';
|
import ReplyIndicator from 'soapbox/features/compose/components/reply-indicator';
|
||||||
import AccountContainer from 'soapbox/containers/account-container';
|
|
||||||
|
|
||||||
import Motion from '../../util/optional-motion';
|
import Motion from '../../util/optional-motion';
|
||||||
|
|
||||||
|
@ -56,16 +55,7 @@ const ActionsModal: React.FC<IActionsModal> = ({ status, actions, onClick, onClo
|
||||||
{({ top }) => (
|
{({ top }) => (
|
||||||
<div className='modal-root__modal actions-modal' style={{ top: `${top}%` }}>
|
<div className='modal-root__modal actions-modal' style={{ top: `${top}%` }}>
|
||||||
{status && (
|
{status && (
|
||||||
<Stack space={2} className='border-b border-solid border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800'>
|
<ReplyIndicator className='actions-modal__status rounded-b-none' status={status} hideActions />
|
||||||
<AccountContainer
|
|
||||||
key={status.account as string}
|
|
||||||
id={status.account as string}
|
|
||||||
showProfileHoverCard={false}
|
|
||||||
withLinkToProfile={false}
|
|
||||||
timestamp={status.created_at}
|
|
||||||
/>
|
|
||||||
<StatusContent status={status} />
|
|
||||||
</Stack>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<ul className={clsx({ 'with-status': !!status })}>
|
<ul className={clsx({ 'with-status': !!status })}>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import { remoteInteraction } from 'soapbox/actions/interactions';
|
import { remoteInteraction } from 'soapbox/actions/interactions';
|
||||||
import { Button, Modal, Stack, Text } from 'soapbox/components/ui';
|
import { Button, Form, Input, Modal, Stack, Text } from 'soapbox/components/ui';
|
||||||
import { useAppSelector, useAppDispatch, useFeatures, useInstance, useRegistrationStatus } from 'soapbox/hooks';
|
import { useAppSelector, useAppDispatch, useFeatures, useInstance, useRegistrationStatus } from 'soapbox/hooks';
|
||||||
import toast from 'soapbox/toast';
|
import toast from 'soapbox/toast';
|
||||||
|
|
||||||
|
@ -104,9 +104,8 @@ const UnauthorizedModal: React.FC<IUnauthorizedModal> = ({ action, onClose, acco
|
||||||
secondaryText={isOpen ? <FormattedMessage id='account.register' defaultMessage='Sign up' /> : undefined}
|
secondaryText={isOpen ? <FormattedMessage id='account.register' defaultMessage='Sign up' /> : undefined}
|
||||||
>
|
>
|
||||||
<div className='remote-interaction-modal__content'>
|
<div className='remote-interaction-modal__content'>
|
||||||
<form className='simple_form remote-interaction-modal__fields' onSubmit={onSubmit}>
|
<Form className='remote-interaction-modal__fields' onSubmit={onSubmit}>
|
||||||
<input
|
<Input
|
||||||
type='text'
|
|
||||||
placeholder={intl.formatMessage(messages.accountPlaceholder)}
|
placeholder={intl.formatMessage(messages.accountPlaceholder)}
|
||||||
name='remote_follow[acct]'
|
name='remote_follow[acct]'
|
||||||
value={account}
|
value={account}
|
||||||
|
@ -116,7 +115,7 @@ const UnauthorizedModal: React.FC<IUnauthorizedModal> = ({ action, onClose, acco
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<Button type='submit' theme='primary'>{button}</Button>
|
<Button type='submit' theme='primary'>{button}</Button>
|
||||||
</form>
|
</Form>
|
||||||
<div className='remote-interaction-modal__divider'>
|
<div className='remote-interaction-modal__divider'>
|
||||||
<Text align='center'>
|
<Text align='center'>
|
||||||
<FormattedMessage id='remote_interaction.divider' defaultMessage='or' />
|
<FormattedMessage id='remote_interaction.divider' defaultMessage='or' />
|
||||||
|
|
|
@ -56,7 +56,7 @@ const UploadArea: React.FC<IUploadArea> = ({ active, onClose }) => {
|
||||||
<Stack space={3} justifyContent='center' alignItems='center'>
|
<Stack space={3} justifyContent='center' alignItems='center'>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/cloud-upload.svg')}
|
src={require('@tabler/icons/cloud-upload.svg')}
|
||||||
className='h-12 w-12 text-white text-opacity-90'
|
className='h-12 w-12 text-white/90'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Text size='xl' theme='white'>
|
<Text size='xl' theme='white'>
|
||||||
|
|
|
@ -72,7 +72,6 @@ import {
|
||||||
Lists,
|
Lists,
|
||||||
Bookmarks,
|
Bookmarks,
|
||||||
Settings,
|
Settings,
|
||||||
MediaDisplay,
|
|
||||||
EditProfile,
|
EditProfile,
|
||||||
EditEmail,
|
EditEmail,
|
||||||
EditPassword,
|
EditPassword,
|
||||||
|
@ -301,7 +300,6 @@ const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) =>
|
||||||
<WrappedRoute path='/settings/email' page={DefaultPage} component={EditEmail} content={children} />
|
<WrappedRoute path='/settings/email' page={DefaultPage} component={EditEmail} content={children} />
|
||||||
<WrappedRoute path='/settings/password' page={DefaultPage} component={EditPassword} content={children} />
|
<WrappedRoute path='/settings/password' page={DefaultPage} component={EditPassword} content={children} />
|
||||||
<WrappedRoute path='/settings/account' page={DefaultPage} component={DeleteAccount} content={children} />
|
<WrappedRoute path='/settings/account' page={DefaultPage} component={DeleteAccount} content={children} />
|
||||||
<WrappedRoute path='/settings/media_display' page={DefaultPage} component={MediaDisplay} content={children} />
|
|
||||||
<WrappedRoute path='/settings/mfa' page={DefaultPage} component={MfaForm} exact />
|
<WrappedRoute path='/settings/mfa' page={DefaultPage} component={MfaForm} exact />
|
||||||
<WrappedRoute path='/settings/tokens' page={DefaultPage} component={AuthTokenList} content={children} />
|
<WrappedRoute path='/settings/tokens' page={DefaultPage} component={AuthTokenList} content={children} />
|
||||||
<WrappedRoute path='/settings' page={DefaultPage} component={Settings} content={children} />
|
<WrappedRoute path='/settings' page={DefaultPage} component={Settings} content={children} />
|
||||||
|
|
|
@ -238,10 +238,6 @@ export function Settings() {
|
||||||
return import(/* webpackChunkName: "features/settings" */'../../settings');
|
return import(/* webpackChunkName: "features/settings" */'../../settings');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function MediaDisplay() {
|
|
||||||
return import(/* webpackChunkName: "features/settings" */'../../settings/media-display');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function EditProfile() {
|
export function EditProfile() {
|
||||||
return import(/* webpackChunkName: "features/edit_profile" */'../../edit-profile');
|
return import(/* webpackChunkName: "features/edit_profile" */'../../edit-profile');
|
||||||
}
|
}
|
||||||
|
|
|
@ -706,8 +706,6 @@
|
||||||
"filters.context_header": "Filter contexts",
|
"filters.context_header": "Filter contexts",
|
||||||
"filters.context_hint": "One or multiple contexts where the filter should apply",
|
"filters.context_hint": "One or multiple contexts where the filter should apply",
|
||||||
"filters.filters_list_context_label": "Filter contexts:",
|
"filters.filters_list_context_label": "Filter contexts:",
|
||||||
"filters.filters_list_delete": "Delete",
|
|
||||||
"filters.filters_list_details_label": "Filter settings:",
|
|
||||||
"filters.filters_list_drop": "Drop",
|
"filters.filters_list_drop": "Drop",
|
||||||
"filters.filters_list_hide": "Hide",
|
"filters.filters_list_hide": "Hide",
|
||||||
"filters.filters_list_phrase_label": "Keyword or phrase:",
|
"filters.filters_list_phrase_label": "Keyword or phrase:",
|
||||||
|
|
|
@ -5,11 +5,13 @@
|
||||||
*/
|
*/
|
||||||
import { List as ImmutableList, Map as ImmutableMap, Record as ImmutableRecord, fromJS } from 'immutable';
|
import { List as ImmutableList, Map as ImmutableMap, Record as ImmutableRecord, fromJS } from 'immutable';
|
||||||
|
|
||||||
|
export type ContextType = 'home' | 'public' | 'notifications' | 'thread';
|
||||||
|
|
||||||
// https://docs.joinmastodon.org/entities/filter/
|
// https://docs.joinmastodon.org/entities/filter/
|
||||||
export const FilterRecord = ImmutableRecord({
|
export const FilterRecord = ImmutableRecord({
|
||||||
id: '',
|
id: '',
|
||||||
phrase: '',
|
phrase: '',
|
||||||
context: ImmutableList<string>(),
|
context: ImmutableList<ContextType>(),
|
||||||
whole_word: false,
|
whole_word: false,
|
||||||
expires_at: '',
|
expires_at: '',
|
||||||
irreversible: false,
|
irreversible: false,
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { validId } from 'soapbox/utils/auth';
|
||||||
import ConfigDB from 'soapbox/utils/config-db';
|
import ConfigDB from 'soapbox/utils/config-db';
|
||||||
import { shouldFilter } from 'soapbox/utils/timelines';
|
import { shouldFilter } from 'soapbox/utils/timelines';
|
||||||
|
|
||||||
|
import type { ContextType } from 'soapbox/normalizers/filter';
|
||||||
import type { ReducerChat } from 'soapbox/reducers/chats';
|
import type { ReducerChat } from 'soapbox/reducers/chats';
|
||||||
import type { RootState } from 'soapbox/store';
|
import type { RootState } from 'soapbox/store';
|
||||||
import type { Filter as FilterEntity, Notification } from 'soapbox/types/entities';
|
import type { Filter as FilterEntity, Notification } from 'soapbox/types/entities';
|
||||||
|
@ -85,7 +86,7 @@ export const findAccountByUsername = (state: RootState, username: string) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const toServerSideType = (columnType: string): string => {
|
const toServerSideType = (columnType: string): ContextType => {
|
||||||
switch (columnType) {
|
switch (columnType) {
|
||||||
case 'home':
|
case 'home':
|
||||||
case 'notifications':
|
case 'notifications':
|
||||||
|
@ -105,10 +106,8 @@ type FilterContext = { contextType?: string };
|
||||||
|
|
||||||
export const getFilters = (state: RootState, query: FilterContext) => {
|
export const getFilters = (state: RootState, query: FilterContext) => {
|
||||||
return state.filters.filter((filter) => {
|
return state.filters.filter((filter) => {
|
||||||
return query?.contextType
|
return (!query?.contextType || filter.context.includes(toServerSideType(query.contextType)))
|
||||||
&& filter.context.includes(toServerSideType(query.contextType))
|
&& (filter.expires_at === null || Date.parse(filter.expires_at) > new Date().getTime());
|
||||||
&& (filter.expires_at === null
|
|
||||||
|| Date.parse(filter.expires_at) > new Date().getTime());
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -251,7 +251,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
||||||
/**
|
/**
|
||||||
* Ability to add reactions to chat messages.
|
* Ability to add reactions to chat messages.
|
||||||
*/
|
*/
|
||||||
chatEmojiReactions: v.software === TRUTHSOCIAL,
|
chatEmojiReactions: false, // v.software === TRUTHSOCIAL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pleroma chats API.
|
* Pleroma chats API.
|
||||||
|
@ -309,7 +309,6 @@ const getInstanceFeatures = (instance: Instance) => {
|
||||||
*/
|
*/
|
||||||
chatsWithFollowers: v.software === TRUTHSOCIAL,
|
chatsWithFollowers: v.software === TRUTHSOCIAL,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mastodon's newer solution for direct messaging.
|
* Mastodon's newer solution for direct messaging.
|
||||||
* @see {@link https://docs.joinmastodon.org/methods/timelines/conversations/}
|
* @see {@link https://docs.joinmastodon.org/methods/timelines/conversations/}
|
||||||
|
@ -380,10 +379,10 @@ const getInstanceFeatures = (instance: Instance) => {
|
||||||
emojiReacts: v.software === PLEROMA && gte(v.version, '2.0.0'),
|
emojiReacts: v.software === PLEROMA && gte(v.version, '2.0.0'),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The backend allows only RGI ("Recommended for General Interchange") emoji reactions.
|
* The backend allows only non-RGI ("Recommended for General Interchange") emoji reactions.
|
||||||
* @see PUT /api/v1/pleroma/statuses/:id/reactions/:emoji
|
* @see PUT /api/v1/pleroma/statuses/:id/reactions/:emoji
|
||||||
*/
|
*/
|
||||||
emojiReactsRGI: (v.software === PLEROMA && gte(v.version, '2.2.49')) || v.software === TRUTHSOCIAL,
|
emojiReactsNonRGI: v.software === PLEROMA && lt(v.version, '2.2.49'),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign in with an Ethereum wallet.
|
* Sign in with an Ethereum wallet.
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
// THEME MIXINS
|
|
||||||
|
|
||||||
// standard container drop shadow
|
|
||||||
@mixin standard-panel-shadow {
|
|
||||||
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// common properties for all standard containers
|
|
||||||
@mixin standard-panel {
|
|
||||||
@include standard-panel-shadow;
|
|
||||||
border-radius: 10px;
|
|
||||||
background: var(--foreground-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SHORTCUTS
|
|
||||||
@mixin input-placeholder($color) {
|
|
||||||
&::-webkit-input-placeholder { color: $color; }
|
|
||||||
&::-moz-placeholder { color: $color; }
|
|
||||||
&:-ms-input-placeholder { color: $color; }
|
|
||||||
&:-moz-placeholder { color: $color; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin avatar-radius {
|
|
||||||
border-radius: 50%;
|
|
||||||
background: transparent no-repeat;
|
|
||||||
background-position: 50%;
|
|
||||||
background-clip: padding-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin avatar-size($size: 48px) {
|
|
||||||
width: $size;
|
|
||||||
height: $size;
|
|
||||||
background-size: $size $size;
|
|
||||||
}
|
|
|
@ -1,5 +1,3 @@
|
||||||
@import 'mixins';
|
|
||||||
@import 'themes';
|
|
||||||
@import 'variables';
|
@import 'variables';
|
||||||
@import 'fonts';
|
@import 'fonts';
|
||||||
@import 'basics';
|
@import 'basics';
|
||||||
|
@ -9,7 +7,6 @@
|
||||||
@import 'rtl';
|
@import 'rtl';
|
||||||
@import 'accessibility';
|
@import 'accessibility';
|
||||||
@import 'navigation';
|
@import 'navigation';
|
||||||
@import 'placeholder';
|
|
||||||
@import 'autosuggest';
|
@import 'autosuggest';
|
||||||
|
|
||||||
// COMPONENTS
|
// COMPONENTS
|
||||||
|
@ -17,7 +14,6 @@
|
||||||
@import 'components/dropdown-menu';
|
@import 'components/dropdown-menu';
|
||||||
@import 'components/modal';
|
@import 'components/modal';
|
||||||
@import 'components/compose-form';
|
@import 'components/compose-form';
|
||||||
@import 'components/emoji-reacts';
|
|
||||||
@import 'components/status';
|
@import 'components/status';
|
||||||
@import 'components/reply-mentions';
|
@import 'components/reply-mentions';
|
||||||
@import 'components/detailed-status';
|
@import 'components/detailed-status';
|
||||||
|
@ -29,7 +25,6 @@
|
||||||
@import 'components/react-toggle';
|
@import 'components/react-toggle';
|
||||||
@import 'components/video-player';
|
@import 'components/video-player';
|
||||||
@import 'components/audio-player';
|
@import 'components/audio-player';
|
||||||
@import 'components/filters';
|
|
||||||
@import 'components/crypto-donate';
|
@import 'components/crypto-donate';
|
||||||
@import 'components/aliases';
|
@import 'components/aliases';
|
||||||
@import 'components/icon';
|
@import 'components/icon';
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
.autosuggest-input {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autosuggest-input input,
|
|
||||||
.react-datepicker__input-container input {
|
.react-datepicker__input-container input {
|
||||||
// display: block;
|
// display: block;
|
||||||
// box-sizing: border-box;
|
// box-sizing: border-box;
|
||||||
|
|
|
@ -8,64 +8,9 @@ body.with-modals {
|
||||||
@apply overflow-hidden;
|
@apply overflow-hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
|
||||||
&.lighter {
|
|
||||||
background: var(--brand-color--med);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.player {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.embed {
|
|
||||||
background: var(--brand-color--faint);
|
|
||||||
margin: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
|
|
||||||
.container {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.admin {
|
|
||||||
background: var(--brand-color--med);
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.error {
|
|
||||||
@apply text-gray-400;
|
|
||||||
position: absolute;
|
|
||||||
text-align: center;
|
|
||||||
background: var(--brand-color--med);
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.dialog {
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 20px;
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: 28px;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: this is needed for React HotKeys performance. Removing this
|
// Note: this is needed for React HotKeys performance. Removing this
|
||||||
// will cause severe performance degradation on Safari.
|
// will cause severe performance degradation on Safari.
|
||||||
div[tabindex="-1"]:focus {
|
div[tabindex='-1']:focus {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,28 +20,6 @@ div[tabindex="-1"]:focus {
|
||||||
|
|
||||||
noscript {
|
noscript {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
img {
|
|
||||||
width: 200px;
|
|
||||||
opacity: 0.5;
|
|
||||||
animation: flicker 4s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
div {
|
|
||||||
@apply text-gray-400;
|
|
||||||
font-size: 14px;
|
|
||||||
margin: 30px auto;
|
|
||||||
max-width: 400px;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--highlight-text-color);
|
|
||||||
text-decoration: underline;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.emojione {
|
.emojione {
|
||||||
|
@ -105,6 +28,6 @@ noscript {
|
||||||
|
|
||||||
// Virtuoso empty placeholder fix.
|
// Virtuoso empty placeholder fix.
|
||||||
// https://gitlab.com/petyosi/soapbox-fe/-/commit/1e22c39934b60e5e186de804060ecfdf1955b506
|
// https://gitlab.com/petyosi/soapbox-fe/-/commit/1e22c39934b60e5e186de804060ecfdf1955b506
|
||||||
div[data-viewport-type="window"] {
|
div[data-viewport-type='window'] {
|
||||||
position: static !important;
|
position: static !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,69 +1,51 @@
|
||||||
.audio-player {
|
.audio-player {
|
||||||
overflow: hidden;
|
@apply relative box-border overflow-hidden rounded-[10px] bg-black pb-11;
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
background: $base-shadow-color;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding-bottom: 44px;
|
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
|
|
||||||
&.editable {
|
&.editable {
|
||||||
border-radius: 0;
|
@apply rounded-none h-full;
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-player__volume::before,
|
.video-player__volume::before,
|
||||||
.video-player__seek::before {
|
.video-player__seek::before {
|
||||||
background: currentcolor;
|
@apply bg-current opacity-[15];
|
||||||
opacity: 0.15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-player__seek__buffer {
|
.video-player__seek__buffer {
|
||||||
background: currentcolor;
|
@apply bg-current opacity-20;
|
||||||
opacity: 0.2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-player__buttons button {
|
.video-player__buttons button {
|
||||||
color: currentcolor;
|
@apply text-current opacity-[75];
|
||||||
opacity: 0.75;
|
|
||||||
|
|
||||||
&:active,
|
&:active,
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
color: currentcolor;
|
@apply text-current opacity-100;
|
||||||
opacity: 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-player__time-sep,
|
.video-player__time-sep,
|
||||||
.video-player__time-total,
|
.video-player__time-total,
|
||||||
.video-player__time-current {
|
.video-player__time-current {
|
||||||
color: currentcolor;
|
@apply text-current;
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-player__seek::before,
|
.video-player__seek::before,
|
||||||
.video-player__seek__buffer,
|
.video-player__seek__buffer,
|
||||||
.video-player__seek__progress {
|
.video-player__seek__progress {
|
||||||
top: 0;
|
@apply top-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-player__seek__handle {
|
.video-player__seek__handle {
|
||||||
top: -4px;
|
@apply -top-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-player__controls {
|
.video-player__controls {
|
||||||
padding-top: 10px;
|
@apply pt-2.5 bg-transparent;
|
||||||
background: transparent;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-spoiler-audio {
|
.media-spoiler-audio {
|
||||||
background-size: cover;
|
@apply relative mt-2 block cursor-pointer border-0 bg-cover bg-center bg-no-repeat;
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-top: 8px;
|
|
||||||
position: relative;
|
|
||||||
border: 0;
|
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,79 +1,3 @@
|
||||||
.column {
|
|
||||||
width: 350px;
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex: 1 1 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 631px) {
|
|
||||||
.column {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
padding: 10px;
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-right: 5px;
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
padding-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.column-link {
|
|
||||||
@apply text-gray-900;
|
|
||||||
background: var(--brand-color--med);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 16px;
|
|
||||||
padding: 15px;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus,
|
|
||||||
&:active {
|
|
||||||
background: var(--brand-color--faint);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--transparent {
|
|
||||||
@apply bg-transparent;
|
|
||||||
color: var(--background-color);
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus,
|
|
||||||
&:active {
|
|
||||||
@apply text-gray-900 bg-transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: var(--brand-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.svg-icon.column-link__icon {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column-header__setting-btn {
|
|
||||||
&--link {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
@apply text-gray-400 underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty-column-indicator,
|
.empty-column-indicator,
|
||||||
.error-column {
|
.error-column {
|
||||||
@apply bg-primary-50 dark:bg-gray-700 text-gray-900 dark:text-gray-300 text-center p-10 flex flex-1 items-center justify-center min-h-[160px] rounded-lg;
|
@apply bg-primary-50 dark:bg-gray-700 text-gray-900 dark:text-gray-300 text-center p-10 flex flex-1 items-center justify-center min-h-[160px] rounded-lg;
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: var(--brand-color--hicontrast);
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
|
||||||
|
@ -28,24 +27,21 @@
|
||||||
&__modifiers {
|
&__modifiers {
|
||||||
@apply text-gray-900 text-sm;
|
@apply text-gray-900 text-sm;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
background: var(--background-color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.compose-form__upload-wrapper { overflow: hidden; }
|
&__upload-wrapper { overflow: hidden; }
|
||||||
|
|
||||||
.compose-form__uploads-wrapper {
|
&__uploads-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
&.contains-media {
|
&.contains-media {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-top: 1px solid var(--foreground-color);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.compose-form__upload {
|
&__upload {
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
min-width: 40%;
|
min-width: 40%;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
|
@ -99,7 +95,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.compose-form__upload-thumbnail {
|
&__upload-thumbnail {
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -118,9 +114,21 @@
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.privacy-dropdown {
|
||||||
|
&.active {
|
||||||
|
&.top .privacy-dropdown__value {
|
||||||
|
@apply rounded-t-md;
|
||||||
|
}
|
||||||
|
|
||||||
.privacy-dropdown__dropdown {
|
.privacy-dropdown__dropdown {
|
||||||
@apply absolute bg-white dark:bg-gray-900 z-[1000] rounded-md shadow-lg ml-10 text-sm;
|
@apply block shadow-md;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__dropdown {
|
||||||
|
@apply absolute bg-white dark:bg-gray-900 z-[1000] rounded-md shadow-lg ml-10 text-sm overflow-hidden;
|
||||||
|
|
||||||
&.top {
|
&.top {
|
||||||
transform-origin: 50% 100%;
|
transform-origin: 50% 100%;
|
||||||
|
@ -131,7 +139,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.privacy-dropdown__option {
|
&__option {
|
||||||
@apply flex p-2.5 text-sm text-gray-700 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer;
|
@apply flex p-2.5 text-sm text-gray-700 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
|
@ -149,13 +157,12 @@
|
||||||
&.active {
|
&.active {
|
||||||
@apply hover:bg-gray-200 dark:hover:bg-gray-700;
|
@apply hover:bg-gray-200 dark:hover:bg-gray-700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
@apply flex items-center justify-center mr-2.5 rtl:mr-0 rtl:ml-2.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.privacy-dropdown__option__icon {
|
&__content {
|
||||||
@apply flex items-center justify-center mr-2.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.privacy-dropdown__option__content {
|
|
||||||
@apply flex-auto text-primary-600 dark:text-primary-400;
|
@apply flex-auto text-primary-600 dark:text-primary-400;
|
||||||
|
|
||||||
strong {
|
strong {
|
||||||
|
@ -168,31 +175,5 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.privacy-dropdown.active {
|
|
||||||
.privacy-dropdown__value {
|
|
||||||
background: var(--foreground-color);
|
|
||||||
border-radius: 4px 4px 0 0;
|
|
||||||
box-shadow: 0 -4px 4px rgba($base-shadow-color, 0.1);
|
|
||||||
|
|
||||||
.icon-button {
|
|
||||||
transition: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background: var(--brand-color);
|
|
||||||
|
|
||||||
.icon-button {
|
|
||||||
@apply text-gray-900;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.top .privacy-dropdown__value {
|
|
||||||
@apply rounded-t-md;
|
|
||||||
}
|
|
||||||
|
|
||||||
.privacy-dropdown__dropdown {
|
|
||||||
@apply block shadow-md;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
.emoji-react {
|
|
||||||
@apply inline-block text-gray-900 dark:text-gray-300 no-underline;
|
|
||||||
transition: 0.2s;
|
|
||||||
|
|
||||||
&__emoji {
|
|
||||||
img {
|
|
||||||
@apply w-5 h-5;
|
|
||||||
filter: drop-shadow(2px 0 0 var(--foreground-color));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__count {
|
|
||||||
@apply hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ .emoji-react {
|
|
||||||
@apply -mr-3;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[type='button'] {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-reacts {
|
|
||||||
display: inline-flex;
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-reacts-container {
|
|
||||||
display: inline-flex;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.emoji-react {
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
&__count {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-reacts__count {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-react-selector {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
background-color: var(--foreground-color);
|
|
||||||
padding: 5px 8px;
|
|
||||||
border-radius: 9999px;
|
|
||||||
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
transition: 0.1s;
|
|
||||||
z-index: 999;
|
|
||||||
|
|
||||||
&--visible,
|
|
||||||
&--focused {
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__emoji {
|
|
||||||
display: block;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
padding: 3px;
|
|
||||||
transition: 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus {
|
|
||||||
img {
|
|
||||||
transform: scale(1.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.status .emoji-react-selector {
|
|
||||||
bottom: 100%;
|
|
||||||
left: -20px;
|
|
||||||
|
|
||||||
@media (max-width: 455px) {
|
|
||||||
bottom: 31px;
|
|
||||||
right: 10px;
|
|
||||||
left: auto;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
.filter-settings-panel {
|
|
||||||
.fields-group .two-col {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
width: 100%;
|
|
||||||
justify-content: flex-start;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
div.input {
|
|
||||||
width: 45%;
|
|
||||||
margin-right: 20px;
|
|
||||||
|
|
||||||
.label_input {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 485px) {
|
|
||||||
div.input {
|
|
||||||
width: 100%;
|
|
||||||
margin-right: 5px;
|
|
||||||
|
|
||||||
.label_input {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.input.boolean {
|
|
||||||
.label_input {
|
|
||||||
@apply relative pl-7 text-black dark:text-white;
|
|
||||||
|
|
||||||
label {
|
|
||||||
@apply text-sm;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
@apply static;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type='checkbox'] {
|
|
||||||
position: absolute;
|
|
||||||
top: 3px;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hint {
|
|
||||||
@apply block pl-7 text-xs text-gray-500 dark:text-gray-400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter__container {
|
|
||||||
@apply flex justify-between py-5 px-2 text-sm text-black dark:text-white;
|
|
||||||
|
|
||||||
.filter__phrase,
|
|
||||||
.filter__contexts,
|
|
||||||
.filter__details {
|
|
||||||
@apply py-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.filter__list-label {
|
|
||||||
@apply pr-1 text-gray-500 dark:text-gray-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.filter__list-value span {
|
|
||||||
@apply pr-1 capitalize;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-of-type {
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter__delete {
|
|
||||||
@apply flex items-center h-5 m-2.5 cursor-pointer;
|
|
||||||
|
|
||||||
span.filter__delete-label {
|
|
||||||
@apply text-gray-500 dark:text-gray-400 font-semibold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter__delete-icon {
|
|
||||||
@apply mx-1 text-gray-500 dark:text-gray-400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,46 +12,6 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transition: 0.2s;
|
transition: 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--active {
|
|
||||||
&.svg-icon--home svg {
|
|
||||||
fill: currentcolor;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.icon-tabler-search,
|
|
||||||
svg.icon-tabler-code {
|
|
||||||
stroke-width: 2.3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.icon-tabler-bell,
|
|
||||||
svg.icon-tabler-messages {
|
|
||||||
path:nth-child(2) {
|
|
||||||
fill: currentcolor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.icon-tabler-users {
|
|
||||||
circle,
|
|
||||||
circle + path {
|
|
||||||
fill: currentcolor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.icon-tabler-mail {
|
|
||||||
stroke: var(--background-color);
|
|
||||||
|
|
||||||
rect {
|
|
||||||
fill: currentcolor;
|
|
||||||
stroke: currentcolor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--unread {
|
|
||||||
svg.icon-tabler-bell {
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-button > div {
|
.icon-button > div {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
$media-compact-size: 50px;
|
||||||
|
|
||||||
.media-gallery {
|
.media-gallery {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -6,10 +8,8 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
background-color: var(--brand-color--faint);
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-gallery__item {
|
&__item {
|
||||||
border: 0;
|
border: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -48,9 +48,8 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.media-gallery__item-thumbnail {
|
&-thumbnail {
|
||||||
@apply text-gray-400;
|
@apply text-gray-400;
|
||||||
cursor: zoom-in;
|
cursor: zoom-in;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -67,8 +66,9 @@
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.media-gallery__preview {
|
&__preview {
|
||||||
@apply bg-gray-200 dark:bg-gray-900 rounded-lg;
|
@apply bg-gray-200 dark:bg-gray-900 rounded-lg;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -83,14 +83,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-gallery__gifv {
|
&__gifv {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-gallery__item-gifv-thumbnail {
|
&__item-gifv-thumbnail {
|
||||||
@apply rounded-md;
|
@apply rounded-md;
|
||||||
cursor: zoom-in;
|
cursor: zoom-in;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -102,27 +102,16 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-gallery__gifv__label,
|
&__gifv__label,
|
||||||
.media-gallery__filename__label,
|
&__filename__label,
|
||||||
.media-gallery__file-extension__label {
|
&__file-extension__label {
|
||||||
display: block;
|
@apply pointer-events-none absolute bottom-1.5 left-1.5 z-[1] block bg-black/50 py-0.5 px-1.5 font-semibold text-white opacity-90;
|
||||||
position: absolute;
|
|
||||||
color: #fff;
|
|
||||||
background: rgba($base-overlay-background, 0.5);
|
|
||||||
bottom: 6px;
|
|
||||||
left: 6px;
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 2px;
|
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-weight: 600;
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
opacity: 0.9;
|
|
||||||
transition: opacity 0.1s ease;
|
transition: opacity 0.1s ease;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-gallery__gifv {
|
&__gifv {
|
||||||
&.autoplay {
|
&.autoplay {
|
||||||
.media-gallery__gifv__label {
|
.media-gallery__gifv__label {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -136,9 +125,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$media-compact-size: 50px;
|
&--compact {
|
||||||
|
|
||||||
.media-gallery--compact {
|
|
||||||
height: $media-compact-size !important;
|
height: $media-compact-size !important;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|
||||||
|
@ -162,3 +149,4 @@ $media-compact-size: 50px;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,13 +27,11 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
video {
|
video {
|
||||||
max-width: $media-modal-media-max-width;
|
@apply max-w-full max-h-[80%];
|
||||||
max-height: $media-modal-media-max-height;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-modal__closer {
|
&__closer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -41,7 +39,7 @@
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-modal__navigation {
|
&__navigation {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -55,7 +53,7 @@
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.media-modal__navigation--hidden {
|
&--hidden {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
@ -64,39 +62,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-modal__nav {
|
&__nav {
|
||||||
background: rgba($base-overlay-background, 0.5);
|
@apply absolute top-0 bottom-0 my-auto mx-0 box-border flex h-[20vmax] cursor-pointer items-center border-0 bg-black/50 text-2xl text-white;
|
||||||
box-sizing: border-box;
|
|
||||||
border: 0;
|
|
||||||
color: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 24px;
|
|
||||||
height: 20vmax;
|
|
||||||
margin: auto 0;
|
|
||||||
padding: 30px 15px;
|
padding: 30px 15px;
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) { padding: 30px 2px; }
|
@media screen and (max-width: 600px) {
|
||||||
|
@apply px-0.5;
|
||||||
|
}
|
||||||
|
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
width: 24px;
|
@apply h-6 w-6;
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-modal__nav--left {
|
&--left {
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-modal__nav--right {
|
&--right {
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.media-modal__pagination {
|
&__pagination {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -105,7 +92,7 @@
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-modal__meta {
|
&__meta {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -130,11 +117,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-modal__page-dot {
|
&__page-dot {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-modal__button {
|
&__button {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
width: 12px;
|
width: 12px;
|
||||||
|
@ -143,13 +130,13 @@
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.media-modal__button--active {
|
&--active {
|
||||||
@apply bg-accent-500;
|
@apply bg-accent-500;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.media-modal__close {
|
&__close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
|
@ -163,22 +150,26 @@
|
||||||
width: 48px;
|
width: 48px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.error-modal {
|
.error-modal {
|
||||||
@apply text-gray-900;
|
@apply text-gray-900;
|
||||||
background: var(--background-color);
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
|
||||||
|
|
||||||
.error-modal__body {
|
&__body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
height: 80vh;
|
height: 80vh;
|
||||||
width: 80vw;
|
width: 80vw;
|
||||||
max-width: 520px;
|
max-width: 520px;
|
||||||
max-height: 420px;
|
max-height: 420px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -197,17 +188,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-modal__body {
|
&__footer {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-modal__footer {
|
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
background: var(--background-color);
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 25px;
|
padding: 25px;
|
||||||
|
@ -215,9 +197,9 @@
|
||||||
& > div {
|
& > div {
|
||||||
min-width: 33px;
|
min-width: 33px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.error-modal__nav {
|
&__nav {
|
||||||
color: var(--highlight-text-color);
|
|
||||||
border: 0;
|
border: 0;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
@ -232,45 +214,39 @@
|
||||||
&:focus,
|
&:focus,
|
||||||
&:active {
|
&:active {
|
||||||
@apply text-gray-400;
|
@apply text-gray-400;
|
||||||
background-color: var(--background-color);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-modal {
|
.actions-modal {
|
||||||
@apply flex-col relative text-gray-400 overflow-hidden;
|
@apply flex-col relative text-gray-400 overflow-hidden w-full max-w-lg m-auto bg-white dark:bg-gray-900 shadow-xl rounded-2xl;
|
||||||
border-radius: 10px;
|
max-height: calc(100vh - 3rem);
|
||||||
border: 1px solid var(--background-color);
|
|
||||||
|
&__item-label {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown-menu__separator {
|
.dropdown-menu__separator {
|
||||||
@apply block m-2 h-[1px] bg-gray-200 dark:bg-gray-600;
|
@apply block m-2 h-[1px] bg-gray-200 dark:bg-gray-600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__status {
|
||||||
|
@apply overflow-y-auto max-h-[300px];
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-modal {
|
|
||||||
@apply w-full max-h-full max-w-lg m-auto mb-2 bg-white dark:bg-gray-800;
|
|
||||||
|
|
||||||
.status {
|
|
||||||
overflow-y: auto;
|
|
||||||
max-height: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions-modal__item-label { font-weight: 500; }
|
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
@apply my-2 flex-shrink-0 overflow-y-auto;
|
@apply my-2 flex-shrink-0 overflow-y-auto;
|
||||||
max-height: calc(100vh - 147px);
|
max-height: calc(100vh - 147px);
|
||||||
|
|
||||||
// NOTE - not sure what this is yet, leaving alone for now until I find out.
|
|
||||||
&.with-status { max-height: calc(80vh - 75px); }
|
&.with-status { max-height: calc(80vh - 75px); }
|
||||||
|
|
||||||
li:not(:empty) {
|
li:not(:empty) {
|
||||||
a,
|
a,
|
||||||
button {
|
button {
|
||||||
@apply flex items-center px-4 py-3 text-gray-600 dark:text-gray-300 no-underline hover:bg-gray-100 dark:bg-gray-800 hover:text-gray-800 dark:hover:text-gray-200 text-left;
|
@apply flex items-center px-4 py-3 text-gray-700 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gray-100 dark:focus:bg-primary-800 no-underline text-left;
|
||||||
|
|
||||||
&.destructive {
|
&.destructive {
|
||||||
@apply text-danger-600;
|
@apply text-danger-600 dark:text-danger-400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.svg-icon:first-child {
|
.svg-icon:first-child {
|
||||||
|
@ -278,11 +254,6 @@
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
stroke-width: 1.5;
|
stroke-width: 1.5;
|
||||||
|
|
||||||
&.feather {
|
|
||||||
// Feather icons are a little larger
|
|
||||||
transform: scale(0.9);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
border: 0;
|
border: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-tap-highlight-color: rgba($base-overlay-background, 0);
|
-webkit-tap-highlight-color: #0000;
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
|
||||||
&:focus-within .react-toggle-track {
|
&:focus-within .react-toggle-track {
|
||||||
|
|
|
@ -38,24 +38,7 @@
|
||||||
|
|
||||||
.svg-icon--backspace {
|
.svg-icon--backspace {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--highlight-text-color);
|
|
||||||
width: 22px;
|
width: 22px;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: var(--brand-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.column {
|
|
||||||
.search {
|
|
||||||
@apply border border-solid border-b-gray-900/20;
|
|
||||||
padding: 10px 15px;
|
|
||||||
background-color: var(--foreground-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search__icon .svg-icon {
|
|
||||||
right: 24px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
[column-type='filled'] .status__wrapper,
|
[column-type='filled'] .status__wrapper,
|
||||||
[column-type='filled'] .status-placeholder {
|
[column-type='filled'] .status-placeholder {
|
||||||
@apply rounded-none shadow-none p-4;
|
@apply bg-transparent dark:bg-transparent rounded-none shadow-none p-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-check-box {
|
.status-check-box {
|
||||||
|
@ -78,7 +78,6 @@ a.status-card {
|
||||||
|
|
||||||
.status-card__image {
|
.status-card__image {
|
||||||
flex: 0 0 40%;
|
flex: 0 0 40%;
|
||||||
background: var(--brand-color--med);
|
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
@ -117,8 +116,9 @@ a.status-card {
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
|
|
||||||
&__status {
|
&__status {
|
||||||
@include standard-panel;
|
|
||||||
padding: 15px 0 10px;
|
padding: 15px 0 10px;
|
||||||
|
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
|
|
|
@ -11,17 +11,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-player {
|
.video-player {
|
||||||
overflow: hidden;
|
@apply relative box-border max-w-full overflow-hidden rounded-[10px] bg-black text-white;
|
||||||
position: relative;
|
|
||||||
background: $base-shadow-color;
|
|
||||||
max-width: 100%;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
color: white;
|
|
||||||
|
|
||||||
&.editable {
|
&.editable {
|
||||||
border-radius: 0;
|
@apply rounded-none;
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +57,7 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: linear-gradient(0deg, rgba($base-shadow-color, 0.85) 0, rgba($base-shadow-color, 0.45) 60%, transparent);
|
background: linear-gradient(0deg, #000000d9 0, #00000073 60%, transparent);
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.1s ease;
|
transition: opacity 0.1s ease;
|
||||||
|
@ -199,7 +193,7 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
margin-left: -6px;
|
margin-left: -6px;
|
||||||
transform: translate(0, -50%);
|
transform: translate(0, -50%);
|
||||||
box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2);
|
box-shadow: 1px 2px 6px #0003;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
.no-reduce-motion & {
|
.no-reduce-motion & {
|
||||||
|
@ -272,7 +266,7 @@
|
||||||
height: 12px;
|
height: 12px;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
margin-left: -6px;
|
margin-left: -6px;
|
||||||
box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2);
|
box-shadow: 1px 2px 6px #0003;
|
||||||
|
|
||||||
.no-reduce-motion & {
|
.no-reduce-motion & {
|
||||||
transition: opacity 0.1s ease;
|
transition: opacity 0.1s ease;
|
||||||
|
|
|
@ -2,21 +2,6 @@
|
||||||
|
|
||||||
// TYPEOGRAPHY MIXINS
|
// TYPEOGRAPHY MIXINS
|
||||||
|
|
||||||
// declare the font family using these shortcuts
|
|
||||||
@mixin font-inter { font-family: Inter, Arial, sans-serif !important; }
|
|
||||||
|
|
||||||
// Declare font weights as a numerical value in rendered output
|
|
||||||
// Prevents certain browsers which do not play nice with "light, medium" textual declarations
|
|
||||||
// Numeical values always work more consistently across browsers
|
|
||||||
// Each font-weight is linked with the @font-face declaration to the actual font file
|
|
||||||
@mixin font-weight($weight) {
|
|
||||||
@if $weight == 'light' { font-weight: 300; }
|
|
||||||
@if $weight == 'normal' { font-weight: 400; }
|
|
||||||
@if $weight == 'medium' { font-weight: 500; }
|
|
||||||
@if $weight == 'bold' { font-weight: 700; }
|
|
||||||
@if $weight == 'extrabold' { font-weight: 800; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use these mixins to define font-size and line-height
|
// Use these mixins to define font-size and line-height
|
||||||
// html and body declaration allows developer to pass px value as argument
|
// html and body declaration allows developer to pass px value as argument
|
||||||
// Rendered css will default to "rem" and fall back to "px" for unsupported browsers
|
// Rendered css will default to "rem" and fall back to "px" for unsupported browsers
|
||||||
|
@ -26,10 +11,3 @@
|
||||||
font-size: #{$px + 'px'};
|
font-size: #{$px + 'px'};
|
||||||
font-size: #{$rem + 'rem'};
|
font-size: #{$rem + 'rem'};
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin line-height($size) {
|
|
||||||
$rem: math.div($size, 10);
|
|
||||||
$px: $size;
|
|
||||||
line-height: #{$px + 'px'};
|
|
||||||
line-height: #{$rem + 'rem'};
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,454 +22,8 @@ select {
|
||||||
margin-left: -1px;
|
margin-left: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.simple_form {
|
|
||||||
.input {
|
|
||||||
&.hidden {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.radio_buttons {
|
|
||||||
.radio {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.radio > label {
|
|
||||||
position: relative;
|
|
||||||
padding-left: 28px;
|
|
||||||
|
|
||||||
input {
|
|
||||||
position: absolute;
|
|
||||||
top: -2px;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.boolean {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.label_input > label {
|
|
||||||
@apply text-sm font-medium text-gray-700 dark:text-gray-400;
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: 14px;
|
|
||||||
display: block;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label_input,
|
|
||||||
.hint {
|
|
||||||
padding-left: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label_input__wrapper {
|
|
||||||
position: static;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"] {
|
|
||||||
position: absolute;
|
|
||||||
top: 1px;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
label a {
|
|
||||||
color: var(--highlight-text-color);
|
|
||||||
text-decoration: underline;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:active,
|
|
||||||
&:focus {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
margin: 0 -5px;
|
|
||||||
|
|
||||||
.input {
|
|
||||||
box-sizing: border-box;
|
|
||||||
flex: 1 1 auto;
|
|
||||||
width: 50%;
|
|
||||||
padding: 0 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hint {
|
|
||||||
@apply text-gray-400;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--highlight-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
border-radius: 3px;
|
|
||||||
padding: 0.2em 0.4em;
|
|
||||||
background: var(--background-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
span.hint {
|
|
||||||
display: block;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.hint {
|
|
||||||
@apply text-gray-400;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
&.subtle-hint {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 18px;
|
|
||||||
margin-top: 15px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
@each $lang in $cjk-langs {
|
|
||||||
&:lang(#{$lang}) {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.input.with_floating_label {
|
|
||||||
.label_input {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
& > label {
|
|
||||||
@apply text-gray-900;
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
min-width: 150px;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
select {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.select .hint {
|
|
||||||
margin-top: 6px;
|
|
||||||
margin-left: 150px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
|
||||||
.label_input > label {
|
|
||||||
@apply text-gray-700 dark:text-gray-400;
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: 14px;
|
|
||||||
display: block;
|
|
||||||
word-wrap: break-word;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
flex: 390px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.required abbr {
|
|
||||||
text-decoration: none;
|
|
||||||
color: lighten($error-value-color, 12%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.fields-group {
|
|
||||||
margin-bottom: 25px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.input.radio_buttons .radio label {
|
|
||||||
@apply text-gray-900;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: 14px;
|
|
||||||
display: block;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldset[disabled] {
|
|
||||||
input[type=text],
|
|
||||||
input[type=number],
|
|
||||||
input[type=email],
|
|
||||||
input[type=url],
|
|
||||||
input[type=password],
|
|
||||||
textarea {
|
|
||||||
@apply text-gray-400 border-gray-400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=text],
|
|
||||||
input[type=number],
|
|
||||||
input[type=email],
|
|
||||||
input[type=url],
|
|
||||||
input[type=password],
|
|
||||||
textarea,
|
|
||||||
.rfipbtn {
|
|
||||||
@apply border border-solid border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-black dark:text-white;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 16px;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
outline: 0;
|
|
||||||
font-family: inherit;
|
|
||||||
resize: vertical;
|
|
||||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 8px 12px;
|
|
||||||
transition: 0.2s;
|
|
||||||
|
|
||||||
&:invalid {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus:invalid:not(:placeholder-shown) {
|
|
||||||
border-color: lighten($error-red, 12%);
|
|
||||||
}
|
|
||||||
|
|
||||||
// &:required:valid {
|
|
||||||
// border-color: $valid-value-color;
|
|
||||||
// }
|
|
||||||
|
|
||||||
&:active,
|
|
||||||
&:focus {
|
|
||||||
border-color: var(--brand-color);
|
|
||||||
outline: 2px solid transparent;
|
|
||||||
outline-offset: 2px;
|
|
||||||
box-shadow: rgb(255, 255, 255) 0 0 0 0,
|
|
||||||
var(--brand-color) 0 0 0 1px,
|
|
||||||
rgba(0, 0, 0, 0.05) 0 1px 2px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.rfip {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=text][disabled],
|
|
||||||
input[type=number][disabled],
|
|
||||||
input[type=email][disabled],
|
|
||||||
input[type=url][disabled],
|
|
||||||
input[type=password][disabled],
|
|
||||||
textarea[disabled] {
|
|
||||||
@apply text-gray-400 border-gray-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input.field_with_errors {
|
|
||||||
label {
|
|
||||||
color: lighten($error-red, 12%);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=text],
|
|
||||||
input[type=number],
|
|
||||||
input[type=email],
|
|
||||||
input[type=url],
|
|
||||||
input[type=password],
|
|
||||||
textarea,
|
|
||||||
select {
|
|
||||||
border-color: lighten($error-red, 12%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
display: block;
|
|
||||||
font-weight: 500;
|
|
||||||
color: lighten($error-red, 12%);
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input.disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
margin-top: 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// button,
|
|
||||||
// .button,
|
|
||||||
// .block-button,
|
|
||||||
// .color-swatch {
|
|
||||||
// display: block;
|
|
||||||
// width: 100%;
|
|
||||||
// border: 0;
|
|
||||||
// border-radius: 4px;
|
|
||||||
// background: var(--brand-color);
|
|
||||||
// color: #fff;
|
|
||||||
// line-height: inherit;
|
|
||||||
// height: auto;
|
|
||||||
// padding: 10px;
|
|
||||||
// text-decoration: none;
|
|
||||||
// text-align: center;
|
|
||||||
// box-sizing: border-box;
|
|
||||||
// cursor: pointer;
|
|
||||||
// font-weight: 500;
|
|
||||||
// outline: 0;
|
|
||||||
|
|
||||||
// &:last-child {
|
|
||||||
// margin-right: 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &:hover,
|
|
||||||
// &:active,
|
|
||||||
// &:focus {
|
|
||||||
// background-color: var(--brand-color--hicontrast);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.negative {
|
|
||||||
// background: $error-value-color;
|
|
||||||
|
|
||||||
// &:hover {
|
|
||||||
// background-color: lighten($error-value-color, 5%);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &:active,
|
|
||||||
// &:focus {
|
|
||||||
// background-color: darken($error-value-color, 5%);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.accordion__toggle {
|
|
||||||
// display: inline-block;
|
|
||||||
// width: auto;
|
|
||||||
// border: 0;
|
|
||||||
// border-radius: 0;
|
|
||||||
// background: none;
|
|
||||||
// color: var(--primary-text-color--faint);
|
|
||||||
// font-size: 18px;
|
|
||||||
// line-height: inherit;
|
|
||||||
// height: auto;
|
|
||||||
// padding: 0 10px;
|
|
||||||
// text-transform: none;
|
|
||||||
// text-decoration: none;
|
|
||||||
// text-align: center;
|
|
||||||
// box-sizing: border-box;
|
|
||||||
// cursor: pointer;
|
|
||||||
// font-weight: 500;
|
|
||||||
// outline: 0;
|
|
||||||
// margin-bottom: 0;
|
|
||||||
// margin-right: 10px;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// select {
|
|
||||||
// appearance: none;
|
|
||||||
// background-color: transparent;
|
|
||||||
// background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
|
|
||||||
// background-position: right 0.5rem center;
|
|
||||||
// background-repeat: no-repeat;
|
|
||||||
// background-size: 1.5em 1.5em;
|
|
||||||
// border-radius: 0.375rem;
|
|
||||||
// border: none;
|
|
||||||
// color: var(--gray-500);
|
|
||||||
// display: inline-block;
|
|
||||||
// font-family: var(--font-sans-serif), sans-serif;
|
|
||||||
// font-size: 14px;
|
|
||||||
// height: var(--input-height);
|
|
||||||
// padding-bottom: 0.5rem;
|
|
||||||
// padding-left: 0.75rem;
|
|
||||||
// padding-right: 2.5rem;
|
|
||||||
// padding-top: 0.5rem;
|
|
||||||
// }
|
|
||||||
|
|
||||||
.label_input__wrapper {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: normal;
|
|
||||||
margin-bottom: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.simple_form {
|
|
||||||
.warning {
|
|
||||||
@apply text-gray-900;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background: rgba($error-value-color, 0.5);
|
|
||||||
text-shadow: 1px 1px 0 rgba($base-shadow-color, 0.3);
|
|
||||||
box-shadow: 0 2px 6px rgba($base-shadow-color, 0.4);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
a {
|
|
||||||
@apply text-gray-900 underline;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus,
|
|
||||||
&:active {
|
|
||||||
@apply no-underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: 600;
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
|
|
||||||
@each $lang in $cjk-langs {
|
|
||||||
&:lang(#{$lang}) {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fa {
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.captcha {
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
display: table;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="text"] {
|
|
||||||
border-radius: 0 0 4px 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.input.with_label.toggle .label_input {
|
.input.with_label.toggle .label_input {
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.theme-toggle {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes heartbeat {
|
@keyframes heartbeat {
|
||||||
from {
|
0% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
animation-timing-function: ease-out;
|
animation-timing-function: ease-out;
|
||||||
}
|
}
|
||||||
|
@ -130,26 +130,16 @@
|
||||||
.load-more {
|
.load-more {
|
||||||
@apply block w-full m-0 p-4 border-0 box-border text-gray-900 bg-transparent;
|
@apply block w-full m-0 p-4 border-0 box-border text-gray-900 bg-transparent;
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus {
|
|
||||||
background: var(--brand-color--faint);
|
|
||||||
}
|
|
||||||
|
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
@apply mx-auto;
|
@apply mx-auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.load-gap {
|
|
||||||
border-bottom: 1px solid var(--brand-color--med);
|
|
||||||
}
|
|
||||||
|
|
||||||
.regeneration-indicator {
|
.regeneration-indicator {
|
||||||
@apply text-gray-900;
|
@apply text-gray-900;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
background: var(--accent-color--faint);
|
|
||||||
cursor: default;
|
cursor: default;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
.media-gallery--placeholder {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-image: linear-gradient(
|
|
||||||
90deg,
|
|
||||||
hsla(var(--foreground-color_hsl), 0) 0%,
|
|
||||||
hsla(var(--foreground-color_hsl), 0) 25%,
|
|
||||||
var(--foreground-color) 50%,
|
|
||||||
hsla(var(--foreground-color_hsl), 0) 70%,
|
|
||||||
hsla(var(--foreground-color_hsl), 0) 100%
|
|
||||||
);
|
|
||||||
background-size: 200%;
|
|
||||||
animation: placeholder-pulse 2s infinite;
|
|
||||||
z-index: 1;
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes placeholder-pulse {
|
|
||||||
0% { background-position-x: 200%; }
|
|
||||||
100% { background-position-x: 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-gallery.media-gallery--placeholder {
|
|
||||||
background: none;
|
|
||||||
|
|
||||||
.media-gallery__item {
|
|
||||||
background-color: var(--brand-color--faint);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +1,11 @@
|
||||||
body.rtl {
|
body.rtl {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
|
|
||||||
.column-link__icon {
|
|
||||||
margin-right: 0;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 68px;
|
padding-right: 68px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.privacy-dropdown__dropdown {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.privacy-dropdown__option__icon {
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simple_form .input.with_label.boolean label.checkbox {
|
|
||||||
padding-left: 25px;
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simple_form .input.radio_buttons .radio {
|
|
||||||
left: auto;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simple_form .input.radio_buttons .radio > label {
|
|
||||||
padding-right: 28px;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simple_form .input.boolean label.checkbox {
|
|
||||||
left: auto;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simple_form .input.boolean .label_input,
|
|
||||||
.simple_form .input.boolean .hint {
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// .simple_form select {
|
|
||||||
// background: var(--background-color) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(var(--brand-color--med))}'/></svg>") no-repeat left 8px center / auto 16px;
|
|
||||||
// }
|
|
||||||
|
|
||||||
.table th,
|
.table th,
|
||||||
.table td {
|
.table td {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
@ -67,9 +22,4 @@ body.rtl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.simple_form .input.radio_buttons .radio > label input {
|
|
||||||
left: auto;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
/*
|
|
||||||
# CSS VARIABLE NAMING CONVENTIONS
|
|
||||||
|
|
||||||
Primary variables are fully-formed CSS properties.
|
|
||||||
Form: --{primary-name}
|
|
||||||
Examples:
|
|
||||||
--brand-color
|
|
||||||
--accent-color
|
|
||||||
--primary-text-color
|
|
||||||
|
|
||||||
Meta-variables are combined to make primary variables.
|
|
||||||
Form: --{primary-name}_{property}
|
|
||||||
Examples:
|
|
||||||
--brand-color_h (int, hue)
|
|
||||||
--brand-color_s (percent, saturation)
|
|
||||||
--brand-color_l (percent, lightness)
|
|
||||||
--brand-color_hsl (csv of the 3 variables above)
|
|
||||||
|
|
||||||
Modifiers are variations of primary variables made by modifying their meta-values.
|
|
||||||
Form: --{primary-name}--{modifier}
|
|
||||||
Examples:
|
|
||||||
--brand-color--faint
|
|
||||||
--brand-color--hicontrast
|
|
||||||
--primary-text-color--faint
|
|
||||||
*/
|
|
||||||
|
|
||||||
body,
|
|
||||||
.site-preview {
|
|
||||||
// Primary variables
|
|
||||||
--brand-color: hsl(var(--brand-color_hsl));
|
|
||||||
--accent-color: hsl(var(--accent-color_hsl));
|
|
||||||
--background-color: hsl(var(--background-color_hsl));
|
|
||||||
--foreground-color: hsl(var(--foreground-color_hsl));
|
|
||||||
|
|
||||||
// Meta-variables
|
|
||||||
--brand-color_hsl: var(--brand-color_h), var(--brand-color_s), var(--brand-color_l);
|
|
||||||
--accent-color_hsl: var(--accent-color_h), var(--accent-color_s), var(--accent-color_l);
|
|
||||||
--background-color_hsl: var(--background-color_h), var(--background-color_s), var(--background-color_l);
|
|
||||||
--foreground-color_hsl: var(--foreground-color_h), var(--foreground-color_s), var(--foreground-color_l);
|
|
||||||
--accent-color_h: calc(var(--brand-color_h) - 15);
|
|
||||||
--accent-color_s: 86%;
|
|
||||||
--accent-color_l: 44%;
|
|
||||||
|
|
||||||
// Modifiers
|
|
||||||
--brand-color--faint: hsla(var(--brand-color_hsl), 0.1);
|
|
||||||
--brand-color--med: hsla(var(--brand-color_hsl), 0.2);
|
|
||||||
--accent-color--faint: hsla(var(--accent-color_hsl), 0.15);
|
|
||||||
--accent-color--bright: hsl(
|
|
||||||
var(--accent-color_h),
|
|
||||||
var(--accent-color_s),
|
|
||||||
calc(var(--accent-color_l) + 3%)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-mode-light {
|
|
||||||
// Primary variables
|
|
||||||
--highlight-text-color: hsl(
|
|
||||||
var(--brand-color_h),
|
|
||||||
var(--brand-color_s),
|
|
||||||
calc(var(--brand-color_l) - 8%)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Meta-variables
|
|
||||||
--background-color_h: 0;
|
|
||||||
--background-color_s: 0%;
|
|
||||||
--background-color_l: 94.9%;
|
|
||||||
--foreground-color_h: 0;
|
|
||||||
--foreground-color_s: 0%;
|
|
||||||
--foreground-color_l: 100%;
|
|
||||||
|
|
||||||
// Modifiers
|
|
||||||
--brand-color--hicontrast: hsl(
|
|
||||||
var(--brand-color_h),
|
|
||||||
var(--brand-color_s),
|
|
||||||
calc(var(--brand-color_l) - 5%)
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -25,11 +25,6 @@
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: var(--highlight-text-color);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-moz-focus-inner {
|
&::-moz-focus-inner {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
@ -75,8 +70,7 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.image-loader__preview-canvas {
|
.image-loader__preview-canvas {
|
||||||
max-width: $media-modal-media-max-width;
|
@apply max-w-full max-h-[80%];
|
||||||
max-height: $media-modal-media-max-height;
|
|
||||||
background: url('../assets/images/void.png') repeat;
|
background: url('../assets/images/void.png') repeat;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
@ -90,9 +84,7 @@
|
||||||
@apply relative w-full h-full flex items-center justify-center;
|
@apply relative w-full h-full flex items-center justify-center;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
@apply w-auto h-auto object-contain shadow-2xl;
|
@apply w-auto h-auto max-w-full max-h-[80%] object-contain shadow-2xl;
|
||||||
max-width: $media-modal-media-max-width;
|
|
||||||
max-height: $media-modal-media-max-height;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,12 +125,6 @@
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
padding: 7px 0;
|
padding: 7px 0;
|
||||||
|
|
||||||
&:focus,
|
|
||||||
&:active {
|
|
||||||
@apply text-gray-900;
|
|
||||||
border-bottom-color: var(--highlight-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,7 @@
|
||||||
// Commonly used web colors
|
|
||||||
|
|
||||||
$error-red: #df405a !default; // Cerise
|
|
||||||
|
|
||||||
// Variables for defaults in UI
|
|
||||||
$base-shadow-color: #000 !default;
|
|
||||||
$base-overlay-background: #000 !default;
|
|
||||||
$error-value-color: $error-red !default;
|
|
||||||
|
|
||||||
// Language codes that uses CJK fonts
|
// Language codes that uses CJK fonts
|
||||||
/* stylelint-disable-next-line value-keyword-case -- locale filenames */
|
/* stylelint-disable-next-line value-keyword-case -- locale filenames */
|
||||||
$cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW;
|
$cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW;
|
||||||
|
|
||||||
// Variables for components
|
|
||||||
$media-modal-media-max-width: 100%;
|
|
||||||
// put margins on top and bottom of image to avoid the screen covered by image.
|
|
||||||
$media-modal-media-max-height: 80%;
|
|
||||||
|
|
||||||
$no-gap-breakpoint: 415px;
|
|
||||||
|
|
||||||
// CSS variables
|
// CSS variables
|
||||||
// NOTE: Prefer CSS variables whenever possible.
|
// NOTE: Prefer CSS variables whenever possible.
|
||||||
// They're future-proof and more flexible.
|
// They're future-proof and more flexible.
|
||||||
|
|
Loading…
Reference in New Issue