Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions ts/components/StoriesTab.dom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,33 @@ export function StoriesTab({
viewUserStories,
}: PropsType): React.JSX.Element {
const [isMyStories, setIsMyStories] = useState(false);
React.useEffect(() => {
const handlePaste = (ev: ClipboardEvent) => {
if (!ev.clipboardData) return;

const items = Array.from(ev.clipboardData.items);

// Image takes priority over text
const imageItem = items.find(item => item.type.startsWith('image/'));
if (imageItem) {
const file = imageItem.getAsFile();
if (!file) return;
onAddStory(file);
return;
}

// Fall back to text
const text = ev.clipboardData.getData('text/plain');
if (text?.trim()) {
setAddStoryData({ type: 'Text', initialText: text.trim() });
}
};

document.addEventListener('paste', handlePaste);
return () => {
document.removeEventListener('paste', handlePaste);
};
}, []);

function onAddStory(file?: File) {
if (file) {
Expand Down
3 changes: 3 additions & 0 deletions ts/components/StoryCreator.dom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export type PropsType = {
source: LinkPreviewSourceType
) => unknown;
file?: File;
initialText?: string;
i18n: LocalizerType;
isSending: boolean;
linkPreview?: LinkPreviewForUIType;
Expand Down Expand Up @@ -102,6 +103,7 @@ export function StoryCreator({
debouncedMaybeGrabLinkPreview,
distributionLists,
file,
initialText,
getPreferredBadge,
groupConversations,
groupStories,
Expand Down Expand Up @@ -301,6 +303,7 @@ export function StoryCreator({
<TextStoryCreator
debouncedMaybeGrabLinkPreview={debouncedMaybeGrabLinkPreview}
i18n={i18n}
initialText={initialText}
isSending={isSending}
linkPreview={linkPreview}
onClose={onClose}
Expand Down
4 changes: 3 additions & 1 deletion ts/components/TextStoryCreator.dom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export type PropsType = {
options?: MaybeGrabLinkPreviewOptionsType
) => unknown;
i18n: LocalizerType;
initialText: string;
isSending: boolean;
linkPreview?: LinkPreviewForUIType;
onClose: () => unknown;
Expand Down Expand Up @@ -133,6 +134,7 @@ function getBgButtonAriaLabel(
export function TextStoryCreator({
debouncedMaybeGrabLinkPreview,
i18n,
initialText,
isSending,
linkPreview,
onClose,
Expand All @@ -158,7 +160,7 @@ export function TextStoryCreator({
TextBackground.None
);
const [sliderValue, setSliderValue] = useState<number>(100);
const [text, setText] = useState<string>('');
const [text, setText] = useState<string>(initialText ?? '');

const [isColorPickerShowing, setIsColorPickerShowing] = useState(false);
const [colorPickerPopperButtonRef, setColorPickerPopperButtonRef] =
Expand Down
1 change: 1 addition & 0 deletions ts/state/ducks/stories.preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export type AddStoryData = ReadonlyDeep<
}
| {
type: 'Text';
initialText?: string,
sending?: boolean;
}
| undefined
Expand Down
20 changes: 13 additions & 7 deletions ts/state/smart/StoryCreator.preload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,19 @@ export const SmartStoryCreator = memo(function SmartStoryCreator() {
);

const addStoryData = useSelector(getAddStoryData);
let file: File | undefined;
const isSending = addStoryData?.sending || false;
let file: File | undefined;
let initialText: string | undefined;
const isSending = addStoryData?.sending || false;

if (addStoryData?.type === 'Media') {
// Note that the source type is ReadonlyDeep<File>, but browser APIs don't
// support that. Hence the cast.
file = addStoryData.file as File;
}
if (addStoryData?.type === 'Media') {
// Note that the source type is ReadonlyDeep<File>, but browser APIs don't
// support that. Hence the cast.
file = addStoryData.file as File;
}

if (addStoryData?.type === 'Text') {
initialText = addStoryData.initialText;
}

const emojiSkinToneDefault = useSelector(getEmojiSkinToneDefault);
const { onUseEmoji } = useEmojisActions();
Expand Down Expand Up @@ -128,6 +133,7 @@ export const SmartStoryCreator = memo(function SmartStoryCreator() {
groupConversations={groupConversations}
groupStories={groupStories}
hasFirstStoryPostExperience={!hasSetMyStoriesPrivacy}
initialText={initialText}
i18n={i18n}
imageToBlurHash={imageToBlurHash}
isFormattingEnabled={isFormattingEnabled}
Expand Down