Skip to content

Commit ed8566b

Browse files
committed
fix: send correct id when quoting tweet
1 parent 7385f0d commit ed8566b

6 files changed

Lines changed: 27 additions & 19 deletions

File tree

app/components/tweet/TweetActionButtons.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,6 @@ const handleShare = async () => {
177177
</Button>
178178

179179
<!-- Place dialog outside dropdown structure -->
180-
<QuoteTweetDialog v-model:open="showQuoteDialog" :reply-to-tweet="props.tweet" />
180+
<QuoteTweetDialog v-model:open="showQuoteDialog" :quote-to-tweet="props.tweet" />
181181
</div>
182182
</template>

app/components/tweet/composer/QuoteTweetDialog.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { Tweet } from '~~/shared/types/tweets';
55
66
const props = defineProps<{
77
open?: boolean;
8-
replyToTweet: Tweet;
8+
quoteToTweet: Tweet;
99
}>();
1010
1111
const emit = defineEmits<{
@@ -22,14 +22,14 @@ const localOpen = computed({
2222
<UiDialog v-model:open="localOpen">
2323
<UiDialogContent class="h-auto max-w-lg" content-height="h-auto max-h-[95vh]">
2424
<TweetComposer
25-
:reply-to-tweet-id="replyToTweet.id"
25+
:quote-to-tweet-id="quoteToTweet.id"
2626
type="quote"
2727
@posted="emit('update:open', false)"
2828
>
2929
<template #reposted-tweet>
3030
<div class="border-foreground/15 rounded-lg border-1">
3131
<TweetDefaultCard
32-
:tweet="replyToTweet"
32+
:tweet="quoteToTweet"
3333
:is-preview="true"
3434
size-class="rounded-md h-60"
3535
/>

app/components/tweet/composer/TweetComposer.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ import { useTweetComposer } from '~/composables/useTweetComposer';
1111
1212
interface Props {
1313
replyToTweetId?: string | null;
14+
quoteToTweetId?: string | null;
1415
type?: string;
1516
}
1617
1718
const props = withDefaults(defineProps<Props>(), {
1819
type: 'default',
1920
replyToTweetId: null,
21+
quoteToTweetId: null,
2022
});
2123
2224
const tweetContent = ref('');
@@ -25,6 +27,7 @@ const userStore = useUserStore();
2527
const media = ref<MediaItem[]>([]);
2628
2729
const replyToRef = toRef(props, 'replyToTweetId');
30+
const quoteToRef = toRef(props, 'quoteToTweetId');
2831
const {
2932
isPosting,
3033
MAX_LENGTH,
@@ -35,7 +38,7 @@ const {
3538
handlePost,
3639
handleAddMedia,
3740
handleRemoveMedia,
38-
} = useTweetComposer(tweetContent, media, replyToRef);
41+
} = useTweetComposer(tweetContent, media, replyToRef, quoteToRef);
3942
4043
const emit = defineEmits<{
4144
(e: 'posted', tweet: Tweet): void;

app/composables/useTweetComposer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const useTweetComposer = (
1111
tweetContent: Ref<string>,
1212
media: Ref<MediaItem[]>,
1313
replyToTweetId?: Ref<string | null>,
14+
quoteTweetId?: Ref<string | null>,
1415
) => {
1516
const { t } = useI18n();
1617

@@ -70,6 +71,7 @@ export const useTweetComposer = (
7071
content: tweetContent.value,
7172
media: mediaIds,
7273
replyToTweetId: replyToTweetId?.value ?? null,
74+
quoteToTweetId: quoteTweetId?.value ?? null,
7375
});
7476

7577
showToaster('success', t('tweet.composer.post_success') || 'Tweet posted successfully!');

test/nuxt/components/tweet/composer/QuoteTweetDialog.spec.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('QuoteDialog', () => {
2323
avatarUrl: 'https://example.com/avatar.jpg',
2424
};
2525

26-
const mockReplyToTweet = {
26+
const mockquoteToTweet = {
2727
id: 'tweet-123',
2828
content: 'Original tweet content',
2929
author: {
@@ -45,7 +45,7 @@ describe('QuoteDialog', () => {
4545
const wrapper = await mountSuspended(QuoteDialog, {
4646
props: {
4747
open: true,
48-
replyToTweet: mockReplyToTweet,
48+
quoteToTweet: mockquoteToTweet,
4949
},
5050
global: {
5151
plugins: [i18n],
@@ -54,15 +54,15 @@ describe('QuoteDialog', () => {
5454

5555
const composer = wrapper.findComponent(TweetComposer);
5656
expect(composer.exists()).toBe(true);
57-
expect(composer.props('replyToTweetId')).toBe('tweet-123');
57+
expect(composer.props('quoteToTweetId')).toBe('tweet-123');
5858
expect(composer.props('type')).toBe('quote');
5959
});
6060

6161
it('renders TweetDefaultCard in reposted-tweet slot', async () => {
6262
const wrapper = await mountSuspended(QuoteDialog, {
6363
props: {
6464
open: true,
65-
replyToTweet: mockReplyToTweet,
65+
quoteToTweet: mockquoteToTweet,
6666
},
6767
global: {
6868
plugins: [i18n],
@@ -71,15 +71,15 @@ describe('QuoteDialog', () => {
7171

7272
const card = wrapper.findComponent(TweetDefaultCard);
7373
expect(card.exists()).toBe(true);
74-
expect(card.props('tweet')).toEqual(mockReplyToTweet);
74+
expect(card.props('tweet')).toEqual(mockquoteToTweet);
7575
expect(card.props('isPreview')).toBe(true);
7676
});
7777

7878
it('emits update:open with false when tweet is posted', async () => {
7979
const wrapper = await mountSuspended(QuoteDialog, {
8080
props: {
8181
open: true,
82-
replyToTweet: mockReplyToTweet,
82+
quoteToTweet: mockquoteToTweet,
8383
},
8484
global: {
8585
plugins: [i18n],
@@ -97,7 +97,7 @@ describe('QuoteDialog', () => {
9797
const wrapper = await mountSuspended(QuoteDialog, {
9898
props: {
9999
open: false,
100-
replyToTweet: mockReplyToTweet,
100+
quoteToTweet: mockquoteToTweet,
101101
},
102102
global: {
103103
plugins: [i18n],

test/nuxt/composables/useTwetComposer.spec.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ vi.mock('vue-i18n', async () => {
3232
describe('useTweetComposer', () => {
3333
let tweetContent: ReturnType<typeof ref<string>>;
3434
let media: ReturnType<typeof ref<MediaItem[]>>;
35-
let replyToTweetId: ReturnType<typeof ref<string | null>>;
35+
let quoteToTweetId: ReturnType<typeof ref<string | null>>;
3636

3737
const mockUploadImage = vi.fn();
3838
const mockUploadVideo = vi.fn();
@@ -44,7 +44,7 @@ describe('useTweetComposer', () => {
4444

4545
tweetContent = ref('');
4646
media = ref([]);
47-
replyToTweetId = ref(null);
47+
quoteToTweetId = ref(null);
4848

4949
(uploadMediaService as ReturnType<typeof vi.fn>).mockReturnValue({
5050
uploadImage: mockUploadImage,
@@ -94,6 +94,7 @@ describe('useTweetComposer', () => {
9494
expect(mockCreateTweetService).toHaveBeenCalledWith({
9595
content: 'Test tweet',
9696
media: [],
97+
quoteToTweetId: null,
9798
replyToTweetId: null,
9899
});
99100
expect(result).toEqual(mockTweet);
@@ -116,6 +117,7 @@ describe('useTweetComposer', () => {
116117
expect(mockCreateTweetService).toHaveBeenCalledWith({
117118
content: 'Tweet with image',
118119
media: ['media-id-1'],
120+
quoteToTweetId: null,
119121
replyToTweetId: null,
120122
});
121123
expect(result).toEqual(mockTweet);
@@ -137,20 +139,21 @@ describe('useTweetComposer', () => {
137139
expect(result).toEqual(mockTweet);
138140
});
139141

140-
it('includes replyToTweetId when provided', async () => {
141-
replyToTweetId.value = 'parent-tweet-id';
142-
const composer = useTweetComposer(tweetContent, media, replyToTweetId);
142+
it('includes quoteToTweetId when provided', async () => {
143+
quoteToTweetId.value = 'parent-tweet-id';
144+
const composer = useTweetComposer(tweetContent, media, null, quoteToTweetId);
143145
tweetContent.value = 'Reply tweet';
144146

145-
const mockTweet = { id: '2', content: 'Reply tweet', replyTo: 'parent-tweet-id' };
147+
const mockTweet = { id: '2', content: 'Reply tweet', quoteTo: 'parent-tweet-id' };
146148
mockCreateTweetService.mockResolvedValue(mockTweet);
147149

148150
const result = await composer.handlePost();
149151

150152
expect(mockCreateTweetService).toHaveBeenCalledWith({
151153
content: 'Reply tweet',
152154
media: [],
153-
replyToTweetId: 'parent-tweet-id',
155+
quoteToTweetId: 'parent-tweet-id',
156+
replyToTweetId: null,
154157
});
155158
expect(result).toEqual(mockTweet);
156159
});

0 commit comments

Comments
 (0)