-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSelectedOptionController.tsx
135 lines (119 loc) · 5 KB
/
SelectedOptionController.tsx
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
123
124
125
126
127
128
129
130
131
132
133
134
135
//TODO(thePeras): Check this package, its extremely heavy (231.2k, gzipped: 50.8k)
import EmojiPicker, { Theme, EmojiStyle, SuggestionMode } from 'emoji-picker-react'
import { useState, useContext, useRef, useEffect } from 'react'
import CopyOption from './selectedOptionController/CopyOption'
import PasteOption from './selectedOptionController/PasteOption'
import MultipleOptionsContext from '../../../contexts/MultipleOptionsContext'
import { CourseOption } from '../../../@types'
import { ThemeContext } from '../../../contexts/ThemeContext'
import { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover'
import RandomFill from './selectedOptionController/RandomFill'
import { AnalyticsTracker, Feature } from '../../../utils/AnalyticsTracker'
type Props = {
currentOption: CourseOption[]
}
/**
* Interactions with the currently selected option
*/
const SelectedOptionController = ({
currentOption,
}: Props) => {
const { enabled } = useContext(ThemeContext)
const { multipleOptions, setMultipleOptions, selectedOption } = useContext(MultipleOptionsContext);
const [emojiPickerOpen, setEmojiPickerOpen] = useState(false)
let isHovered = false
let isScrollingBack = false
const input = useRef(null)
const [scrollDirection, setScrollDirection] = useState(1); // 1 is right, -1 is left
const inputIsActive = () => document.activeElement === input.current;
//TODO(thePeras): Fix these functions using states and setInterval
const startScroll = () => {
if (inputIsActive()) return;
isHovered = true
input.current.scrollLeft += 5
}
const stopScroll = () => {
if (inputIsActive()) return;
isHovered = false
input.current.scrollLeft = 0
}
const [optionName, setOptionName] = useState(multipleOptions[selectedOption].name ?? '');
useEffect(() => {
setOptionName(multipleOptions[selectedOption].name)
}, [selectedOption, multipleOptions])
const renameOptionName = (event) => {
const newName = event.target.value;
if (newName.length > 35) return;
event.target.value = newName
setMultipleOptions((prevMultipleOptions) => {
const updatedMultipleOptions = prevMultipleOptions.map((item) =>
item.id === multipleOptions[selectedOption].id ? { ...item, name: newName } : item
)
return updatedMultipleOptions;
})
AnalyticsTracker.trackFeature(Feature.OPTION_RENAME);
}
const changeOptionIcon = (newIcon) => {
setMultipleOptions((prevMultipleOptions) => {
const updatedMultipleOptions = prevMultipleOptions.map((item) =>
item.id === multipleOptions[selectedOption].id ? { ...item, icon: newIcon.imageUrl } : item
)
return updatedMultipleOptions;
})
AnalyticsTracker.trackFeature(Feature.OPTION_EMOJI);
AnalyticsTracker.emoji(newIcon.emoji);
}
return (
<div className="flex w-full flex-col sm:flex-row lg:flex-col xl:flex-row xl:content-between xl:gap-5">
<div className="order-2 flex flex-grow gap-2 sm:order-1 lg:order-2 xl:order-1">
<Popover open={emojiPickerOpen} onOpenChange={setEmojiPickerOpen}>
<PopoverTrigger className="aspect-square h-10 w-15 rounded-md p-1 px-2 text-xl bg-lightish dark:bg-darkish border border-slate-200 dark:border-slate-800">
<img
src={multipleOptions[selectedOption]?.icon}
alt={multipleOptions[selectedOption].name}
/>
</PopoverTrigger>
<PopoverContent side="bottom" className="mx-5 w-96 rounded-full bg-lightish p-0 dark:bg-darkish">
<EmojiPicker
width="100%"
searchDisabled={true}
previewConfig={{ showPreview: false }}
theme={enabled ? Theme.DARK : Theme.LIGHT}
suggestedEmojisMode={SuggestionMode.RECENT}
emojiStyle={EmojiStyle.APPLE}
onEmojiClick={(emojiData, e) => {
changeOptionIcon(emojiData)
setEmojiPickerOpen(false)
}}
/>
</PopoverContent>
</Popover>
<input
key={selectedOption}
id="option-name"
spellCheck="false"
ref={input}
value={optionName}
className="w-full resize-none overflow-x-auto scroll-smooth rounded border-none bg-inherit p-1 transition-all font-medium"
onChange={renameOptionName}
onBlur={renameOptionName}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault()
renameOptionName(e)
e.currentTarget.blur() // currentTarget is the element the event handler was attached to
}
}}
onMouseMove={startScroll}
onMouseLeave={stopScroll}
/>
</div>
<div className="order-1 flex items-center gap-1 p-1 sm:order-2 sm:w-1/3 lg:order-1 lg:w-auto xl:order-2">
<CopyOption currentOption={currentOption} className="sm:py-0 xl:p-1" />
<PasteOption />
<RandomFill className="sm:py-0 xl:p-1" />
</div>
</div>
)
}
export default SelectedOptionController