-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathShareButton.tsx
More file actions
122 lines (107 loc) Β· 3.53 KB
/
ShareButton.tsx
File metadata and controls
122 lines (107 loc) Β· 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { useRef, useState } from 'react'
import { toPng } from 'html-to-image'
import styled from 'styled-components'
import { useToast } from '@/app/providers'
import { Share } from '@/assets/icons'
import GuestCharacter from '@/assets/images/img_character_guest.png'
import MemberCharacter from '@/assets/images/img_character_member.png'
import type { CdCustomData } from '@/entities/playlist'
import ShareImage from '@/features/share/ui/ShareImage'
import { useCopyCdShareUrl } from '@/shared/lib/useCopyCdShareUrl'
import { flexRowCenter, myCdButton } from '@/shared/styles/mixins'
import { BottomSheet, Button, Cd, ScrollCarousel, SvgButton } from '@/shared/ui'
interface ShareButtonProps {
playlistId: number
stickers?: CdCustomData[]
type?: 'MY' | 'DISCOVER'
}
const ShareButton = ({ playlistId, stickers, type = 'DISCOVER' }: ShareButtonProps) => {
const [isBottomSheetOpen, setIsBottomSheetOpen] = useState(false)
const [selectedIndex, setSelectedIndex] = useState(0)
const { toast } = useToast()
const { copyCdShareUrl } = useCopyCdShareUrl()
const shareRefs = useRef<(HTMLDivElement | null)[]>([])
const slides = [
{ id: 'cd', content: <Cd variant="customize" bgColor="none" stickers={stickers} /> },
{
id: 'member',
content: <img src={MemberCharacter} alt="Member Character" width={220} height={220} />,
},
{
id: 'guest',
content: <img src={GuestCharacter} alt="Guest Character" width={220} height={220} />,
},
]
const handleShare = () => setIsBottomSheetOpen(true)
const handleSaveImage = async () => {
const currentRef = shareRefs.current[selectedIndex]
if (!currentRef) return
try {
const dataUrl = await toPng(currentRef)
const link = document.createElement('a')
link.href = dataUrl
link.download = `playlist-${playlistId}-${slides[selectedIndex].id}.png`
link.click()
toast('IMAGE')
} catch (e) {
console.error(e)
}
}
return (
<>
<ButtonWrapper $isMy={type === 'MY'} onClick={handleShare}>
<SvgButton icon={Share} width={type === 'MY' ? 16 : 24} height={type === 'MY' ? 16 : 24} />
</ButtonWrapper>
<BottomSheet
isOpen={isBottomSheetOpen}
onClose={() => setIsBottomSheetOpen(false)}
height="fit-content"
>
<BottomSheetWrapper>
<ScrollCarousel
gap={20}
onSelectIndex={setSelectedIndex}
options={{ dragFree: false, containScroll: false }}
>
{slides.map((slide, idx) => (
<div
key={slide.id}
ref={(el: HTMLDivElement | null) => {
shareRefs.current[idx] = el
}}
>
<ShareImage>{slide.content}</ShareImage>
</div>
))}
</ScrollCarousel>
<ButtonBar>
<Button onClick={handleSaveImage} size="M" state="secondary">
μ΄λ―Έμ§λ‘ μ μ₯
</Button>
<Button onClick={() => copyCdShareUrl(playlistId)} size="M" state="secondary">
λ§ν¬ 볡μ¬
</Button>
</ButtonBar>
</BottomSheetWrapper>
</BottomSheet>
</>
)
}
export default ShareButton
const BottomSheetWrapper = styled.div`
display: flex;
flex-direction: column;
gap: 24px;
justify-content: center;
`
const ButtonBar = styled.div`
${flexRowCenter}
gap: 10px;
width: 100%;
& button {
flex: 1;
}
`
const ButtonWrapper = styled.div<{ $isMy: boolean }>`
${({ $isMy }) => $isMy && myCdButton};
`