Sticker upload affordances, fix 'recent media'
This commit is contained in:
parent
21c00f51bd
commit
f60e9b9c9f
7 changed files with 34 additions and 6 deletions
|
@ -3047,6 +3047,14 @@
|
||||||
"message": "Add your stickers",
|
"message": "Add your stickers",
|
||||||
"description": "Title for the drop stage of the sticker creator"
|
"description": "Title for the drop stage of the sticker creator"
|
||||||
},
|
},
|
||||||
|
"StickerCreator--DropStage--removeSticker": {
|
||||||
|
"message": "Remove sticker",
|
||||||
|
"description": "Label for the X button used to remove a staged sticker"
|
||||||
|
},
|
||||||
|
"StickerCreator--DropStage--dragDrop": {
|
||||||
|
"message": "Click or drag/drop a file to add a sticker",
|
||||||
|
"description": "Shown on the + section of the file addition stage of sticker pack creation"
|
||||||
|
},
|
||||||
"StickerCreator--DropStage--help": {
|
"StickerCreator--DropStage--help": {
|
||||||
"message": "Stickers must be in PNG, APNG, or WebP format with a transparent background and 512x512 pixels. Recommended margin is 16px.",
|
"message": "Stickers must be in PNG, APNG, or WebP format with a transparent background and 512x512 pixels. Recommended margin is 16px.",
|
||||||
"description": "Help text for the drop stage of the sticker creator"
|
"description": "Help text for the drop stage of the sticker creator"
|
||||||
|
|
|
@ -202,11 +202,17 @@ export const StickerFrame = React.memo(
|
||||||
<div className={styles.guide} />
|
<div className={styles.guide} />
|
||||||
) : null}
|
) : null}
|
||||||
{mode === 'add' && onDrop ? (
|
{mode === 'add' && onDrop ? (
|
||||||
<DropZone onDrop={onDrop} inner onDragActive={setDragActive} />
|
<DropZone
|
||||||
|
label={i18n('StickerCreator--DropStage--dragDrop')}
|
||||||
|
onDrop={onDrop}
|
||||||
|
inner
|
||||||
|
onDragActive={setDragActive}
|
||||||
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{mode === 'removable' ? (
|
{mode === 'removable' ? (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
aria-label={i18n('StickerCreator--DropStage--removeSticker')}
|
||||||
className={styles.closeButton}
|
className={styles.closeButton}
|
||||||
onClick={handleRemove}
|
onClick={handleRemove}
|
||||||
// Reverse the mouseenter/leave logic for the remove button so
|
// Reverse the mouseenter/leave logic for the remove button so
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { Props as StickerFrameProps, StickerFrame } from './StickerFrame';
|
||||||
import { stickersDuck } from '../store';
|
import { stickersDuck } from '../store';
|
||||||
import { DropZone, Props as DropZoneProps } from '../elements/DropZone';
|
import { DropZone, Props as DropZoneProps } from '../elements/DropZone';
|
||||||
import { processStickerImage } from '../util/preload';
|
import { processStickerImage } from '../util/preload';
|
||||||
|
import { useI18n } from '../util/i18n';
|
||||||
|
|
||||||
const queue = new PQueue({ concurrency: 3, timeout: 1000 * 60 * 2 });
|
const queue = new PQueue({ concurrency: 3, timeout: 1000 * 60 * 2 });
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ export type InnerGridProps = Props & {
|
||||||
|
|
||||||
const InnerGrid = SortableContainer(
|
const InnerGrid = SortableContainer(
|
||||||
({ ids, mode, showGuide }: InnerGridProps) => {
|
({ ids, mode, showGuide }: InnerGridProps) => {
|
||||||
|
const i18n = useI18n();
|
||||||
const containerClassName = ids.length > 0 ? styles.grid : styles.drop;
|
const containerClassName = ids.length > 0 ? styles.grid : styles.drop;
|
||||||
const frameMode = mode === 'add' ? 'removable' : 'pick-emoji';
|
const frameMode = mode === 'add' ? 'removable' : 'pick-emoji';
|
||||||
|
|
||||||
|
@ -94,7 +96,10 @@ const InnerGrid = SortableContainer(
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<DropZone onDrop={handleDrop} />
|
<DropZone
|
||||||
|
label={i18n('StickerCreator--DropStage--dragDrop')}
|
||||||
|
onDrop={handleDrop}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,5 +8,5 @@ import { action } from '@storybook/addon-actions';
|
||||||
import { DropZone } from './DropZone';
|
import { DropZone } from './DropZone';
|
||||||
|
|
||||||
storiesOf('Sticker Creator/elements', module).add('DropZone', () => {
|
storiesOf('Sticker Creator/elements', module).add('DropZone', () => {
|
||||||
return <DropZone onDrop={action('onDrop')} />;
|
return <DropZone label="This is the label" onDrop={action('onDrop')} />;
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { useStickerDropzone } from '../util/useStickerDropzone';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
readonly inner?: boolean;
|
readonly inner?: boolean;
|
||||||
|
readonly label: string;
|
||||||
onDrop(files: Array<string>): unknown;
|
onDrop(files: Array<string>): unknown;
|
||||||
onDragActive?(active: boolean): unknown;
|
onDragActive?(active: boolean): unknown;
|
||||||
};
|
};
|
||||||
|
@ -26,7 +27,7 @@ const getClassName = ({ inner }: Props, isDragActive: boolean) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DropZone: React.ComponentType<Props> = props => {
|
export const DropZone: React.ComponentType<Props> = props => {
|
||||||
const { inner, onDrop, onDragActive } = props;
|
const { inner, label, onDrop, onDragActive } = props;
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
|
|
||||||
const handleDrop = React.useCallback(
|
const handleDrop = React.useCallback(
|
||||||
|
@ -50,6 +51,7 @@ export const DropZone: React.ComponentType<Props> = props => {
|
||||||
<div
|
<div
|
||||||
{...getRootProps({ className: getClassName(props, isDragActive) })}
|
{...getRootProps({ className: getClassName(props, isDragActive) })}
|
||||||
role="button"
|
role="button"
|
||||||
|
area-label={label}
|
||||||
>
|
>
|
||||||
<input {...getInputProps()} />
|
<input {...getInputProps()} />
|
||||||
<svg viewBox="0 0 36 36" width="36px" height="36px">
|
<svg viewBox="0 0 36 36" width="36px" height="36px">
|
||||||
|
|
|
@ -8,6 +8,14 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
padding: 2px;
|
||||||
|
|
||||||
|
// We'd really like to use focus-within-visible or :has(:focus-visible), to ensure that
|
||||||
|
// this doesn't show when using the mouse, but neither are ready yet!
|
||||||
|
&:focus-within {
|
||||||
|
outline: 2px solid -webkit-focus-ring-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
|
@ -48,6 +56,5 @@
|
||||||
.label {
|
.label {
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 1px;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1870,7 +1870,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
showAllMedia(): void {
|
showAllMedia(): void {
|
||||||
if (this.panels && this.panels.length) {
|
if (document.querySelectorAll('.module-media-gallery').length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue