Skip to content

Commit 098cae4

Browse files
committed
feat(sharing): add Xiaohongshu sharing guide to three share-option popups
1 parent e94cb81 commit 098cae4

File tree

4 files changed

+578
-79
lines changed

4 files changed

+578
-79
lines changed

spx-gui/src/components/project/sharing/ProjectDirectShare.vue

Lines changed: 206 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,68 @@
3333
<PlatformSelector v-model="selectedPlatform" @update:model-value="handlePlatformChange" />
3434
<div v-if="!selectedPlatform?.shareType.supportURL" class="share-content-row">
3535
<Poster ref="posterCompRef" :project-data="props.projectData" />
36-
<div class="qrcode side">
37-
<img v-if="qrCodeData" :src="qrCodeData" alt="QR Code" />
38-
<div v-else-if="selectedPlatform?.shareType.supportImage" class="loading-container">
39-
<div class="loading-icon">⏳</div>
40-
<span class="loading-text">{{ $t({ en: 'Generating QR code...', zh: '正在生成二维码...' }) }}</span>
36+
37+
<div class="side-content">
38+
<div v-if="selectedPlatform?.basicInfo.name === 'xiaohongshu'" class="xiaohongshu-guide">
39+
<h3>📱 {{ $t({ en: 'How to share to Xiaohongshu?', zh: '如何分享到小红书?' }) }}</h3>
40+
41+
<div class="guide-steps">
42+
<div class="step">
43+
<span class="step-number">1️⃣</span>
44+
<div class="step-content">
45+
<strong>{{ $t({ en: 'Download Poster', zh: '下载海报' }) }}</strong>
46+
<p>{{ $t({ en: 'Click the button below to save poster', zh: '点击下方按钮保存海报到设备' }) }}</p>
47+
</div>
48+
</div>
49+
50+
<div class="step">
51+
<span class="step-number">2️⃣</span>
52+
<div class="step-content">
53+
<strong>{{ $t({ en: 'Open Xiaohongshu App', zh: '打开小红书APP' }) }}</strong>
54+
<p>{{ $t({ en: 'Tap "+" to create new post', zh: '点击"+"号发布新笔记' }) }}</p>
55+
</div>
56+
</div>
57+
58+
<div class="step">
59+
<span class="step-number">3️⃣</span>
60+
<div class="step-content">
61+
<strong>{{ $t({ en: 'Upload & Share', zh: '上传分享' }) }}</strong>
62+
<p>{{ $t({ en: 'Select the downloaded poster to share', zh: '选择刚下载的海报进行分享' }) }}</p>
63+
</div>
64+
</div>
65+
</div>
66+
67+
<div class="api-notice">
68+
<span class="notice-icon">💡</span>
69+
<p>
70+
{{
71+
$t({ en: 'Manual upload required due to API limitations', zh: '由于API限制,需要手动上传,感谢理解' })
72+
}}
73+
</p>
74+
</div>
75+
76+
<button class="download-btn primary" :disabled="!posterCompRef" @click="handleDownloadPoster">
77+
{{ $t({ en: 'Download Poster', zh: '下载海报' }) }}
78+
</button>
4179
</div>
42-
<div v-else class="unsupported-container">
43-
<div class="unsupport-icon">❌</div>
44-
<span class="unsupported-text">{{ $t({ en: 'Unsupported', zh: '暂不支持' }) }}</span>
80+
81+
<div v-else class="qrcode-section">
82+
<img v-if="qrCodeData" :src="qrCodeData" alt="QR Code" />
83+
<div v-else-if="selectedPlatform?.shareType.supportImage" class="loading-container">
84+
<div class="loading-icon">⏳</div>
85+
<span class="loading-text">{{ $t({ en: 'Generating QR code...', zh: '正在生成二维码...' }) }}</span>
86+
</div>
87+
<div v-else class="unsupported-container">
88+
<div class="unsupport-icon">❌</div>
89+
<span class="unsupported-text">{{ $t({ en: 'Unsupported', zh: '暂不支持' }) }}</span>
90+
</div>
91+
<button class="download-btn" @click="handleDownloadPoster">
92+
{{ $t({ en: 'Download Poster', zh: '下载海报' }) }}
93+
</button>
4594
</div>
46-
<button class="download-btn" @click="handleDownloadPoster">
47-
{{ $t({ en: 'Download Poster', zh: '下载海报' }) }}
48-
</button>
4995
</div>
5096
</div>
97+
5198
<div v-else class="qrcode">
5299
<img v-if="qrCodeData" :src="qrCodeData" alt="QR Code" />
53100
</div>
@@ -106,7 +153,6 @@ async function getPlatformShareURL(platform: PlatformConfig) {
106153
if (platform.shareType.supportURL && platform.shareFunction.shareURL) {
107154
return platform.shareFunction.shareURL(projectSharingLink.value)
108155
} else if (platform.shareType.supportImage && platform.shareFunction.shareImage) {
109-
// 生成海报文件并传递给shareImage方法
110156
if (posterCompRef.value == null) {
111157
throw new Error('Poster component not ready')
112158
}
@@ -138,7 +184,6 @@ const handleDownloadPoster = async () => {
138184
link.href = url
139185
link.download = `${props.projectData.name}-poster.png`
140186
link.click()
141-
// 清理URL对象
142187
URL.revokeObjectURL(url)
143188
} catch (error) {
144189
console.error('Failed to download poster:', error)
@@ -177,7 +222,7 @@ const handleDownloadPoster = async () => {
177222
display: flex;
178223
align-items: stretch;
179224
justify-content: center;
180-
gap: 48px;
225+
gap: 18px;
181226
}
182227
183228
.qrcode.side {
@@ -233,4 +278,151 @@ const handleDownloadPoster = async () => {
233278
transform: rotate(360deg);
234279
}
235280
}
281+
.side-content {
282+
display: flex;
283+
flex-direction: column;
284+
align-items: center;
285+
justify-content: center;
286+
min-width: 300px;
287+
}
288+
289+
.xiaohongshu-guide {
290+
width: 100%;
291+
max-width: 320px;
292+
padding: 10px;
293+
background: linear-gradient(135deg, #fff5f5 0%, #ffeef0 100%);
294+
border-radius: 12px;
295+
border: 2px solid #ffb3ba;
296+
box-shadow: 0 4px 12px rgba(255, 0, 53, 0.1);
297+
298+
h3 {
299+
margin: 0 0 16px 0;
300+
font-size: 16px;
301+
font-weight: 600;
302+
color: #ff0035;
303+
text-align: center;
304+
}
305+
}
306+
307+
.guide-steps {
308+
margin-bottom: 16px;
309+
310+
.step {
311+
display: flex;
312+
align-items: flex-start;
313+
margin-bottom: 12px;
314+
315+
&:last-child {
316+
margin-bottom: 0;
317+
}
318+
}
319+
320+
.step-number {
321+
font-size: 16px;
322+
margin-right: 10px;
323+
flex-shrink: 0;
324+
line-height: 1.2;
325+
}
326+
327+
.step-content {
328+
flex: 1;
329+
330+
strong {
331+
display: block;
332+
font-size: 13px;
333+
font-weight: 600;
334+
color: #333;
335+
margin-bottom: 2px;
336+
}
337+
338+
p {
339+
font-size: 12px;
340+
color: #666;
341+
margin: 0;
342+
line-height: 1.3;
343+
}
344+
}
345+
}
346+
347+
.api-notice {
348+
display: flex;
349+
align-items: flex-start;
350+
margin-bottom: 16px;
351+
padding: 10px 12px;
352+
background: rgba(255, 255, 255, 0.8);
353+
border-radius: 8px;
354+
355+
.notice-icon {
356+
font-size: 14px;
357+
margin-right: 6px;
358+
flex-shrink: 0;
359+
}
360+
361+
p {
362+
margin: 0;
363+
font-size: 11px;
364+
color: #888;
365+
line-height: 1.4;
366+
}
367+
}
368+
369+
.download-btn {
370+
width: 100%;
371+
margin-top: 8px;
372+
border-radius: 6px;
373+
padding: 8px 16px;
374+
border: 1px solid var(--ui-color-primary-main);
375+
background: var(--ui-color-primary-main);
376+
color: white;
377+
cursor: pointer;
378+
transition: all 0.2s ease;
379+
380+
&:hover:not(:disabled) {
381+
background: var(--ui-color-primary-shade);
382+
color: var(--ui-color-primary-main);
383+
}
384+
385+
&:disabled {
386+
background: var(--ui-color-hint-2);
387+
border-color: var(--ui-color-hint-2);
388+
cursor: not-allowed;
389+
}
390+
}
391+
392+
.download-btn.primary {
393+
width: 100%;
394+
background: linear-gradient(135deg, #ff0035 0%, #ff4d6d 100%);
395+
color: white;
396+
border: none;
397+
padding: 12px 20px;
398+
border-radius: 8px;
399+
font-size: 14px;
400+
font-weight: 600;
401+
cursor: pointer;
402+
transition: all 0.3s ease;
403+
404+
&:hover:not(:disabled) {
405+
background: linear-gradient(135deg, #e6002f 0%, #ff3366 100%);
406+
transform: translateY(-1px);
407+
box-shadow: 0 4px 12px rgba(255, 0, 53, 0.3);
408+
}
409+
410+
&:disabled {
411+
opacity: 0.6;
412+
cursor: not-allowed;
413+
}
414+
}
415+
416+
.qrcode-section {
417+
display: flex;
418+
flex-direction: column;
419+
align-items: center;
420+
justify-content: center;
421+
gap: 8px;
422+
423+
img {
424+
width: 100px;
425+
height: 100px;
426+
}
427+
}
236428
</style>

spx-gui/src/components/project/sharing/ProjectPoster.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ defineExpose({
257257
</div>
258258
</div>
259259
</div>
260-
<div style="display: flex; align-items: flex-start; gap: 16px">
260+
<div style="display: flex; align-items: flex-start; justify-content: space-between">
261261
<div class="branding">
262262
<img :src="logo" alt="logo" class="branding-logo" style="height: 40px; vertical-align: middle" />
263263
</div>
@@ -276,14 +276,14 @@ defineExpose({
276276
background-image: url('./posterBackground.jpg');
277277
background-size: cover;
278278
background-position: center;
279-
padding: 32px;
279+
padding: 18px;
280280
display: flex;
281281
flex-direction: column;
282282
position: relative;
283283
overflow: hidden;
284-
/* box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15); */
285284
transition: all 0.3s ease;
286285
max-height: 500px;
286+
margin-top: 10px;
287287
}
288288
289289
.screenshot-area {
@@ -453,7 +453,7 @@ defineExpose({
453453
align-items: center;
454454
height: 60px;
455455
background: rgba(0, 0, 0, 0.1);
456-
padding: 12px 20px;
456+
padding: 12px 6px;
457457
border-radius: 24px;
458458
backdrop-filter: blur(4px);
459459
box-sizing: border-box;

0 commit comments

Comments
 (0)