Skip to content

Commit

Permalink
πŸš€ Release/1.2.1 (#180)
Browse files Browse the repository at this point in the history
πŸš€ Release/1.2.1
  • Loading branch information
yjkwon07 authored Dec 3, 2021
2 parents 97b9044 + bd010e4 commit 7c2e850
Show file tree
Hide file tree
Showing 26 changed files with 146 additions and 84 deletions.
7 changes: 6 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
"source.fixAll.eslint": true
},
"cSpell.words": [
"favorited"
"favorited",
"Gregister",
"Nlogin",
"Nregister",
"Glogin",
"pageview"
],
}
45 changes: 5 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,58 +66,23 @@ urlink(μœ μ–΄λ§ν¬)λŠ” μΈν„°λ„·μ—μ„œ λ¦¬μ„œμΉ˜ν•  λ•Œ, λ‚˜μ€‘μ— λ‹€μ‹œ 보
`development` ν™˜κ²½μ—μ„œλŠ” `chrome api` κΈ°λŠ₯을 μ‚¬μš© ν•  수 μ—†μ–΄ `build`λ₯Ό ν•˜κ³  크둬 μ΅μŠ€ν…μ…˜ 개발 λͺ¨λ“œλ‘œ 확인 κ°€λŠ₯ν•©λ‹ˆλ‹€.

### development

```
npm i
npm run start
```

### production [build]

```
npm i
npm run build
```

### chrome development

```
1. 크둬 μ‹€ν–‰
2. ν™•μž₯ ν”„λ‘œκ·Έλž¨
3. μ••μΆ•ν•΄μ§€λœ ν™•μž₯ ν”„λ‘œκ·Έλž¨μ„ λ‘œλ“œν•©λ‹ˆλ‹€[클릭]
4. build 된 폴더 선택
```

# πŸ—‚ Component Architecture

- [eslint + prettier code convention](https://github.com/urLink-DEV/urLink-frontend/pull/120)
- `μ½”λ“œ μŠ€νƒ€μΌ` 톡일

- [Git flow](https://www.notion.so/Git-flow-dbc4389bac1e4d0b8e570a8157f8b40c)
- κΉƒ μ „λž΅μ„ 톡해 브런치 νžˆμŠ€ν† λ¦¬ `버전관리`κ°€ κ°€λŠ₯

- [폴더 ꡬ쑰](https://github.com/urLink-DEV/urLink-frontend/pull/116)
- μ»΄ν¬λ„ŒνŠΈ 뢄리 μŠ€νƒ€μΌμ„ ν†΅μΌν•˜μ—¬ `CategoryList`, `linkList`, `AppBar`μ˜μ—­μ„ λͺ…ν™•ν•˜κ²Œ λ‚˜λˆ” <br/>
✨ ν˜‘μ—…μ—μ„œ μΌμ–΄λ‚˜λŠ” `code conflict` ν˜„μƒμ„ μ€„μ—¬μ€Œ

- `Container + Component` κ΅¬μ‘°μ—μ„œ `hooks(redux) + Component` ꡬ쑰둜 λ³€κ²½ <br/>
✨ Containerμ—μ„œ μ½”λ“œ 길이가 λ°©λŒ€ν•΄μ§μ„ hooksλ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λ“ˆ κ΄€λ¦¬λ‘œ μ½”λ“œ 길이λ₯Ό 쀄 일 수 μžˆμ—ˆμŒ

- [modules(redux) code convention](https://www.notion.so/modules-code-convention-fe4a0bad389445258d1752909c863209)
- `state`λ₯Ό λ‚΄λ¦¬λŠ” ꡬ쑰둜 μ„€κ³„λ˜μ–΄ `props drilling` ν˜„μƒμ΄ μΌμ–΄λ‚˜ ν•˜λ‚˜μ˜ μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ˜μ‘΄μ„± 결합이 많이 λ˜μ—ˆμŒ <br/>
✨ `redux` κ΄€λ¦¬λ‘œ μ „μ—­ μƒνƒœ 관리λ₯Ό 톡해 μ»΄ν¬λ„ŒνŠΈκ°„μ˜ μ˜μ‘΄μ„± 관계λ₯Ό μ€„μ—¬μ€Œ
- `ContextAPI` ➑ `redux` + `redux-thunk` + `redux-saga` <br/>
✨ `Provider`λ₯Ό μ—¬λŸ¬κ°œλ‘œ λ§Œλ“€μ–΄ λ‚΄λ¦¬λŠ” ꡬ쑰보닀 `ν•˜λ‚˜μ˜ Redux Provider`둜 `useSelector`, `useDispatch` ν•˜λŠ”κ²ƒμ΄ 더 μ½”λ“œκ°€ κΉ”λ”ν•˜κ³  `hooks` 와 state λ©”λͺ¨μ œμ΄μ…˜μ΄ λ˜μ–΄ 선택
- API 톡신을 λͺ¨λ“ˆν™”ν•˜μ—¬ `μ»΄ν¬λ„ŒνŠΈ`와 `μ„œλ²„ 톡신(redux-saga)`의 관심사 뢄리 <br/>
✨ μ»΄ν¬λ„ŒνŠΈλŠ” `dispatch`둜 api 톡신을 ν•˜κ³  `api 톡신 λ‚΄μš©`은 `redux-saga`둜 관리

- [둜그인 μœ μ§€](https://github.com/urLink-DEV/urLink-frontend/pull/116)
- μΊμ‹œλ‘œ μ €μž₯된 ν† ν°μœ λ¬΄μ—λ”°λΌ 둜그인 μœ μ§€ κ²°μ •ν•˜μ—¬ νŽ˜μ΄μ§€ κΉœλΉ‘μ΄λŠ” ν˜„μƒ μ—†μ•°

- [chromeApis λͺ¨λ“ˆν™”](https://github.com/urLink-DEV/urLink-frontend/pull/116)
- `development`μ—μ„œλŠ” `chrome api`κ°€ 지원 λ˜μ§€ μ•ŠμœΌλ―€λ‘œ `Promise` ν˜Ήμ€ `λΆ„κΈ°` 둜 `development`와 `production` λͺ¨λ“œμ— 따라 값을 λ‹€λ₯΄κ²Œ 리턴 <br/>
✨ μ»΄ν¬λ„ŒνŠΈμ˜ 관심사 뢄리가 κ°€λŠ₯해짐

- [webpack(craco)](https://github.com/urLink-DEV/urLink-frontend/issues/119)
- `package.json`μ—μ„œ `babel`κ³Ό` webpack` μ˜€λ²„λΌμ΄λ“œλ₯Ό `craco`λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•œκ³³μ—μ„œ κ΄€λ¦¬ν•˜λ„λ‘ μ„€μ •
- single point μ—μ„œ [multiEntry point](https://github.com/urLink-DEV/urLink-frontend/pull/120)둜 λ³€κ²½ν•˜μ—¬ `popup` + `background` + `main` 3개의 ν”„λ‘œμ νŠΈλ₯Ό ν•œ λ²ˆμ— λΉŒλ“œ ν•  수 있게 μ„€μ • <br/>
✨ 개발 μœ μ§€λ³΄μˆ˜ 효율 λ†’μž„
- BundleAnalyzerPlugin μΆ”κ°€ <br/>
✨ λ²ˆλ“€λ§ 크기 μ΅œμ ν™” ν• λ•Œ κ·Έλž˜ν”½μœΌλ‘œ 확인

4. build 된 폴더 선택
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "urlink-chrome-extension",
"version": "1.2.0",
"version": "1.2.1",
"private": true,
"dependencies": {
"@craco/craco": "^6.1.1",
Expand Down
4 changes: 2 additions & 2 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "urLink",
"version": "1.2.0",
"version": "1.2.1",
"manifest_version": 2,
"description": "λΆλ§ˆν¬λ³΄λ‹€ μ†μ‰½κ²Œ μ›Ήμ‚¬μ΄νŠΈλ₯Ό λ³΄κ΄€ν•˜κ³  μ •λ¦¬ν•˜μ„Έμš”.",
"permissions": ["tabs", "<all_urls>", "identity", "history", "notifications"],
"permissions": ["<all_urls>", "identity", "history", "notifications"],
"icons": {
"16": "images/logo/logo16.png",
"24": "images/logo/logo24.png",
Expand Down
13 changes: 9 additions & 4 deletions src/main/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import React, { useEffect } from 'react'

import moment from 'moment'
import { Router } from 'react-chrome-extension-router'
import ReactGA from 'react-ga'
import { useLocation } from 'react-router-dom'

import Snackbar from '@main/components/Toast'
import Home from '@main/pages/Home'
import { useToast } from '@modules/ui'
import { GAPageview, initGA } from '@utils/ga'
import { getAccessToken } from '@utils/http/auth'

import GetStartPage from './pages/Start'
Expand All @@ -16,12 +17,16 @@ import 'moment/locale/ko'
moment.locale('ko')

function App() {
const { pathname } = useLocation()

useEffect(() => {
ReactGA.initialize('UA-207149982-2')
ReactGA.set({ page: window.location.pathname })
ReactGA.pageview(window.location.pathname + window.location.search)
initGA()
}, [])

useEffect(() => {
GAPageview(pathname)
}, [pathname])

return (
<>
<Router>{getAccessToken() ? <Home /> : <GetStartPage />}</Router>
Expand Down
2 changes: 2 additions & 0 deletions src/main/components/ScrollUpButton/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { ArrowUpward as ArrowUpwardIcon } from '@material-ui/icons'
import clsx from 'clsx'

import ExtendedFab from '@main/components/ExtendedFab'
import { GAEvent } from '@utils/ga'

import useStyles from './style'

function ScrollUpButton({ targetRef, className, open }) {
const classes = useStyles()

const handleScrollUp = () => {
GAEvent('슀크둀 μ—… λ²„νŠΌ', '슀크둀 μ—… λ²„νŠΌ 클릭')
scrollTo(targetRef.current, 0, 500)
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/pages/Home/AppBar/AlarmList/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { alarmNoticeSelector, alarmNoticeReadNoticeThunk, alarmNoticeNoReturnNot
import { categorySelector } from '@modules/category'
import { linksRead } from '@modules/link'
import { useToast } from '@modules/ui'
import { GAEvent } from '@utils/ga'

import useStyles, { SmallAvatar } from './style'

Expand All @@ -43,6 +44,7 @@ function AlarmList() {
await dispatch(alarmNoticeReadNoticeThunk({ alarm_id: alarm.id }))
dispatch(linksRead.request({ categoryId: selectedCategory?.id }, { key: selectedCategory?.id }))
createTab(alarm.url_path)
GAEvent('μ•±λ°”', 'μ•ŒλžŒ 링크 클릭')
} catch (error) {
openToast({ type: 'error', message: 'μ˜ˆμƒμΉ˜ λͺ»ν•œ μ—λŸ¬κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.' })
}
Expand All @@ -57,6 +59,7 @@ function AlarmList() {
await dispatch(alarmNoticeNoReturnNoticeThunk({ alarm_id }))
dispatch(linksRead.request({ categoryId: selectedCategory?.id }, { key: selectedCategory?.id }))
openToast({ type: 'success', message: 'μ•ŒλžŒμ„ μ‚­μ œν–ˆμŠ΅λ‹ˆλ‹€.' })
GAEvent('μ•±λ°”', 'μ•ŒλžŒ 링크 μ‚­μ œ μ™„λ£Œ')
} catch (error) {
openToast({ type: 'error', message: 'μ•ŒλžŒμ„ μ‚­μ œν•˜μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.' })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import newTabImg from '@assets/images/new-tab.svg'
import { useToast } from '@modules/ui'
import { createTab } from '@utils/chromeApis/tab'
import copyLink from '@utils/copyLink'
import { GAEvent } from '@utils/ga'

import useStyles from './style'

Expand All @@ -21,6 +22,7 @@ function History({ isSelected = false, data = {}, ...props }) {
const handleNewTab = useCallback(
(e) => {
e.stopPropagation()
GAEvent('방문기둝', '링크 μƒˆ νƒ­ μ—΄κΈ°')
createTab(data.url)
},
[data.url]
Expand All @@ -29,6 +31,7 @@ function History({ isSelected = false, data = {}, ...props }) {
const handleLinkCopy = useCallback(
(e) => {
e.stopPropagation()
GAEvent('방문기둝', '링크 볡사 ν•˜κΈ°')
copyLink(data.url)
openToast({ type: 'success', message: '링크가 볡사 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.' })
},
Expand Down
8 changes: 8 additions & 0 deletions src/main/pages/Home/AppBar/DragableHistoryList/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import SearchBar from '@main/components/SearchBar'
import { useHistoryLinks } from '@modules/historyLink'
import { DROP_ZONE, DRAG, useDrag, useDropZone } from '@modules/ui'
import { createTabList } from '@utils/chromeApis/tab'
import { GAEvent } from '@utils/ga'

import History from './History'
import HistoryDateTitle from './HistoryDateTitle'
Expand Down Expand Up @@ -65,6 +66,7 @@ function DragableHistoryList() {
}
setDragData(dragListData)
e.dataTransfer.setDragImage(dragBoxRef.current, 110, 35)
GAEvent('방문기둝', '링크 λ“œλž˜κ·Έ μ‹œμž‘')
},
[selectedList, setDragData]
)
Expand All @@ -73,6 +75,7 @@ function DragableHistoryList() {
() => (e) => {
e.stopPropagation()
setSelectedList([])
GAEvent('방문기둝', '링크 λ“œλž˜κ·Έ μ™„λ£Œ')
},
[]
)
Expand All @@ -82,6 +85,7 @@ function DragableHistoryList() {
const isSelected = selectedList.find((item) => item.id === id)
if (isSelected) setSelectedList(selectedList.filter((data) => data.id !== id))
else setSelectedList((listData) => listData.concat({ id, path }))
GAEvent('방문기둝', '링크 선택 ν•˜κΈ°')
},
[selectedList]
)
Expand All @@ -106,13 +110,15 @@ function DragableHistoryList() {
return debounce(() => {
setSelectedList([])
handleResetInput()
GAEvent('방문기둝', 'μƒˆλ‘œκ³ μΉ¨')
}, 400)
}, [handleResetInput])

const handleSelectName = useCallback(
(e) => {
handleResetInput()
setSelectedName(e.target.value)
GAEvent('방문기둝', '검색 주제 λ°”κΎΈκΈ°')
},
[handleResetInput]
)
Expand All @@ -125,10 +131,12 @@ function DragableHistoryList() {
// date
const handleChangeDate = useCallback((date) => {
setDateKeyword(date)
GAEvent('방문기둝', 'κ²€μƒ‰λ°”μ—μ„œ λ‚ μ§œ λ°”κΎΈκΈ°')
}, [])

const handleOpenNewTab = useCallback(() => {
createTabList(selectedList.reduce((list, link) => list.concat(link.path), []))
GAEvent('방문기둝', '볡수의 링크 μƒˆ νƒ­ μ—΄κΈ°')
}, [selectedList])

useEffect(() => {
Expand Down
13 changes: 8 additions & 5 deletions src/main/pages/Home/AppBar/Profile/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import defaultProfileImg from '@assets/images/logo/profileImg.png'
import { TermsModal, AlertModal } from '@main/components/modals'
import { useDialog, useToast, MODAL_NAME } from '@modules/ui'
import { useUserData, userRemoveThunk, userLogoutThunk } from '@modules/user'
import { GAEvent } from '@utils/ga'

import useStyles from './style'

Expand All @@ -18,11 +19,12 @@ function Profile() {
const dispatch = useDispatch()
const { data } = useUserData()
const { open: termsOpen, toggle: termsToggle, close: termsClose } = useDialog(TERMS_MODAL)
const { open: removUserOpen, toggle: removUserToggle, close: removUserClose } = useDialog(REMOVE_USER_ALERT_MODAL)
const { open: removeUserOpen, toggle: removeUserToggle, close: removeUserClose } = useDialog(REMOVE_USER_ALERT_MODAL)
const { openToast } = useToast()

const handleLogout = useCallback(async () => {
try {
GAEvent('μ•±λ°”', 'μœ μ € λ‘œκ·Έμ•„μ›ƒ ν•˜κΈ°')
await dispatch(userLogoutThunk())
window.location.href = '/index.html'
} catch (error) {
Expand All @@ -32,6 +34,7 @@ function Profile() {

const handleRemoveUser = useCallback(async () => {
try {
GAEvent('μ•±λ°”', 'μœ μ € νƒˆν‡΄ ν•˜κΈ°')
await dispatch(userRemoveThunk())
window.location.href = '/index.html'
} catch (error) {
Expand Down Expand Up @@ -61,7 +64,7 @@ function Profile() {
<Button className={classes.profileBtn} size="small" onClick={termsToggle}>
약관보기
</Button>
<Button className={classes.profileBtn} size="small" onClick={removUserToggle}>
<Button className={classes.profileBtn} size="small" onClick={removeUserToggle}>
νšŒμ›νƒˆν‡΄
</Button>
</Grid>
Expand All @@ -75,12 +78,12 @@ function Profile() {
</CardActions>
</Card>
{termsOpen && <TermsModal open={termsOpen} onClose={termsClose} onYesText="λ‹«κΈ°" onYesClick={termsClose} />}
{removUserOpen && (
{removeUserOpen && (
<AlertModal
openBool={removUserOpen}
openBool={removeUserOpen}
btnYesText="νƒˆν‡΄"
contentText="μΉ΄ν…Œκ³ λ¦¬μ™€ μ €μž₯ν•œ 링크가 λͺ¨λ‘ μ‚­μ œλ˜λ©° 볡ꡬ할 수 μ—†μŠ΅λ‹ˆλ‹€. 정말 νƒˆν‡΄ν•˜μ‹œκ² μ–΄μš”?"
handleClose={removUserClose}
handleClose={removeUserClose}
handleYesClick={handleRemoveUser}
/>
)}
Expand Down
12 changes: 10 additions & 2 deletions src/main/pages/Home/AppBar/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import historyImg from '@assets/images/history.png'
import personImg from '@assets/images/person.png'
import { alarmNoticeSelector } from '@modules/alarmNotice'
import { useHistoryLinks } from '@modules/historyLink'
import { GAEvent } from '@utils/ga'

import AlarmList from './AlarmList'
import DragableHistoryList from './DragableHistoryList'
Expand Down Expand Up @@ -37,6 +38,7 @@ function AppBar() {
onClick={() => {
reload()
setOpenHistory((open) => !open)
GAEvent('μ•±λ°”', '방문기둝 λ“œλ‘œμ–΄ λ²„νŠΌ 클릭')
}}
>
<Avatar variant="square" className={classes.imgButton} src={historyImg} alt="history button" />
Expand All @@ -46,7 +48,10 @@ function AppBar() {
button
ref={alarmRef}
aria-describedby="alarm-popover"
onClick={() => setOpenAlarm((open) => !open)}
onClick={() => {
setOpenAlarm((open) => !open)
GAEvent('μ•±λ°”', 'μ•ŒλžŒ νŒμ—… λ²„νŠΌ 클릭')
}}
>
<Badge
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
Expand All @@ -71,7 +76,10 @@ function AppBar() {
button
ref={profileRef}
aria-describedby="profile-popover"
onClick={() => setOpenProfile((open) => !open)}
onClick={() => {
setOpenProfile((open) => !open)
GAEvent('μ•±λ°”', 'ν”„λ‘œν•„ νŒμ—… λ²„νŠΌ 클릭')
}}
>
<Avatar variant="square" src={personImg} alt="profile-popover-button" className={classes.imgButton} />
</StyledListItem>
Expand Down
Loading

0 comments on commit 7c2e850

Please sign in to comment.