Skip to content

Commit 57a20b2

Browse files
authored
Merge pull request #148 from medyo/develop
implement: dnd mode
2 parents 8335442 + 9ea2147 commit 57a20b2

31 files changed

+679
-91
lines changed

public/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<title>New Tab</title>
1717
<% } %>
1818
</head>
19-
<body>
19+
<body class="preload">
2020
<noscript>You need to enable JavaScript to run this app.</noscript>
2121
<div id="root"></div>
2222
</body>

public/startup.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
// Blocking script to avoid the initial background flickering (switching from light to dark)
22
// https://stackoverflow.com/a/63033934/3495717
3+
4+
function isDNDModeActive(DNDDuration) {
5+
if (DNDDuration === 'always') {
6+
return true
7+
} else if (typeof DNDDuration === 'object') {
8+
return Boolean(DNDDuration.value && DNDDuration.countdown - new Date().getTime() > 0)
9+
} else {
10+
return false
11+
}
12+
}
313
try {
4-
var theme = JSON.parse(localStorage.preferences_storage).theme || 'dark'
14+
var state = JSON.parse(localStorage.preferences_storage).state
15+
var theme = state.theme || 'dark'
516
document.documentElement.classList.add(theme)
6-
} catch (e) {
7-
console.log(e)
8-
}
17+
18+
var DNDDuration = state.DNDDuration || 'never'
19+
if (isDNDModeActive(DNDDuration)) {
20+
document.documentElement.classList.add('dndState')
21+
}
22+
} catch (e) {}

src/App.js

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,43 @@
11
import React, { Suspense, useEffect, useLayoutEffect, useState } from 'react'
22
import 'react-contexify/dist/ReactContexify.css'
33
import 'src/assets/App.css'
4-
import { Header } from 'src/components/Layout'
4+
import { DNDLayout, Header } from 'src/components/Layout'
55
import { BookmarksSidebar } from 'src/features/bookmarks'
66
import { MarketingBanner } from 'src/features/MarketingBanner'
77
import { setupAnalytics, setupIdentification, trackPageView } from 'src/lib/analytics'
88
import { useUserPreferences } from 'src/stores/preferences'
99
import { diffBetweenTwoDatesInDays } from 'src/utils/DateUtils'
10-
import { AppContentLayout, ScrollCardsNavigator } from './components/Layout'
10+
import { AppContentLayout } from './components/Layout'
1111
import { isWebOrExtensionVersion } from './utils/Environment'
1212
import { getAppVersion } from './utils/Os'
1313

1414
const OnboardingModal = React.lazy(() =>
1515
import('src/features/onboarding').then((module) => ({ default: module.OnboardingModal }))
1616
)
1717

18+
const intersectionCallback = (entries) => {
19+
entries.forEach((entry) => {
20+
if (!entry.isIntersecting) {
21+
document.documentElement.classList.remove('dndState')
22+
} else {
23+
document.documentElement.classList.add('dndState')
24+
}
25+
})
26+
}
27+
1828
function App() {
1929
const [showSideBar, setShowSideBar] = useState(false)
2030
const [showSettings, setShowSettings] = useState(false)
2131
const [showOnboarding, setShowOnboarding] = useState(true)
22-
const { onboardingCompleted, firstSeenDate, markOnboardingAsCompleted, maxVisibleCards } =
23-
useUserPreferences()
32+
const {
33+
onboardingCompleted,
34+
firstSeenDate,
35+
markOnboardingAsCompleted,
36+
maxVisibleCards,
37+
isDNDModeActive,
38+
DNDDuration,
39+
setDNDDuration,
40+
} = useUserPreferences()
2441

2542
useLayoutEffect(() => {
2643
if (!onboardingCompleted && getAppVersion() <= '1.15.9') {
@@ -32,16 +49,40 @@ function App() {
3249
// eslint-disable-next-line react-hooks/exhaustive-deps
3350
}, [onboardingCompleted, firstSeenDate])
3451

35-
useEffect(() => {
52+
useLayoutEffect(() => {
3653
document.documentElement.style.setProperty('--max-visible-cards', maxVisibleCards)
3754
}, [maxVisibleCards])
3855

3956
useEffect(() => {
57+
document.body.classList.remove('preload')
4058
setupAnalytics()
4159
setupIdentification()
42-
trackPageView('home')
4360
}, [])
4461

62+
useEffect(() => {
63+
trackPageView('home', isDNDModeActive())
64+
if (!isDNDModeActive() && DNDDuration !== 'never') {
65+
setDNDDuration('never')
66+
}
67+
}, [DNDDuration, isDNDModeActive, setDNDDuration])
68+
69+
useLayoutEffect(() => {
70+
let dndContent = document.querySelector('.DNDContent')
71+
let observer = new IntersectionObserver(intersectionCallback, {
72+
threshold: 0.1,
73+
})
74+
75+
if (dndContent) {
76+
observer.observe(dndContent)
77+
} else {
78+
document.documentElement.classList.remove('dndState')
79+
}
80+
81+
return () => {
82+
observer.disconnect()
83+
}
84+
}, [DNDDuration])
85+
4586
return (
4687
<>
4788
<MarketingBanner />
@@ -61,8 +102,11 @@ function App() {
61102
showSettings={showSettings}
62103
setShowSettings={setShowSettings}
63104
/>
64-
<ScrollCardsNavigator />
65-
<AppContentLayout setShowSettings={setShowSettings} />
105+
106+
<div className="layoutLayers hideScrollBar">
107+
{isDNDModeActive() && <DNDLayout />}
108+
<AppContentLayout setShowSettings={setShowSettings} />
109+
</div>
66110
<BookmarksSidebar showSidebar={showSideBar} onClose={() => setShowSideBar(false)} />
67111
</div>
68112
</>

src/assets/App.css

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
html {
44
background: var(--background-color);
55
scroll-behavior: smooth;
6+
overflow: hidden;
67
}
78
body {
89
color: var(--primary-text-color);
910
font-family: 'nunito';
1011
font-size: 100%;
1112
}
13+
1214
.transitionBgColor {
1315
transition: background-color 0.3s ease-in-out;
1416
}
@@ -36,6 +38,7 @@ a {
3638
color: var(--primary-text-color);
3739
display: flex;
3840
flex-direction: column;
41+
height: 100vh;
3942
}
4043
.errorMsg {
4144
text-align: center;
@@ -62,8 +65,11 @@ a {
6265
align-items: center;
6366
align-content: center;
6467
flex-wrap: wrap;
65-
height: 86px;
68+
height: 10vh;
6669
margin: 0.5% 1% 0px 1%;
70+
position: sticky;
71+
z-index: 1;
72+
top: 0;
6773
}
6874

6975
.AppFooter {
@@ -91,18 +97,19 @@ a {
9197

9298
.AppContent {
9399
position: relative;
94-
overflow-y: hidden;
95-
padding: 12px 0;
100+
margin: 0;
96101
}
97102
.Cards {
98-
padding: 1%;
99103
flex: 1 1 auto;
100104
display: flex;
101105
gap: 12px;
102106
position: relative;
103107
overflow-y: hidden;
108+
justify-content: space-between;
104109
scroll-snap-type: x mandatory;
105110
scroll-padding-left: 12px;
111+
padding-top: 2vh;
112+
height: 87vh;
106113
}
107114
.HorizontalScroll {
108115
-ms-overflow-style: none;
@@ -114,10 +121,7 @@ a {
114121

115122
.extras {
116123
flex-direction: row;
117-
margin-right: 16px;
118124
align-content: center;
119-
120-
transition: width, left, right, 0.3s;
121125
}
122126
.darkModeBtn {
123127
background-color: var(--dark-mode-background-color) !important;
@@ -140,6 +144,7 @@ a {
140144
display: inline-flex;
141145
align-items: center;
142146
justify-content: center;
147+
transition: all 0.4s linear;
143148
}
144149
.extraTextBtn {
145150
padding: 0 16px;
@@ -199,7 +204,7 @@ a {
199204
border-radius: 10px;
200205
overflow: hidden;
201206
flex-direction: column;
202-
height: 82vh;
207+
height: 98%;
203208
width: 10vw;
204209
flex: 0 0 auto;
205210
scroll-snap-align: start;
@@ -490,6 +495,8 @@ a {
490495
flex-wrap: wrap;
491496
gap: 4px;
492497
margin-top: 24px;
498+
transition: all 0.3s ease-out;
499+
opacity: 1;
493500
}
494501

495502
.tag {
@@ -772,6 +779,8 @@ Producthunt item
772779
position: relative;
773780
margin: 0 auto;
774781
margin-top: 6px;
782+
transition: all 0.3s ease-out;
783+
opacity: 1;
775784
}
776785
.searchBarIcon {
777786
position: absolute;
@@ -850,7 +859,7 @@ Producthunt item
850859

851860
.scrollButton {
852861
border: none;
853-
position: fixed;
862+
position: absolute;
854863
top: 45%;
855864
margin: 0 1%;
856865
background-color: var(--card-action-button-background);
@@ -1097,7 +1106,7 @@ Producthunt item
10971106
}
10981107
.block {
10991108
width: calc(
1100-
(1800px - 14px * min(5, var(--max-visible-cards))) / min(5, var(--max-visible-cards))
1109+
(1800px - 20px * min(5, var(--max-visible-cards))) / min(5, var(--max-visible-cards))
11011110
);
11021111
}
11031112
}
@@ -1125,6 +1134,37 @@ Producthunt item
11251134
position: relative;
11261135
vertical-align: middle;
11271136
}
1137+
.layoutLayers {
1138+
scroll-snap-type: y mandatory;
1139+
display: flex;
1140+
flex-direction: column;
1141+
height: 100vh;
1142+
overflow-y: scroll;
1143+
margin: 0 1%;
1144+
}
1145+
.layoutLayers > * {
1146+
scroll-snap-align: end;
1147+
}
1148+
1149+
/*Helpers */
11281150
.noMargin {
11291151
margin: 0 !important;
11301152
}
1153+
.marginLeftAuto {
1154+
margin-left: auto;
1155+
}
1156+
1157+
.hideScrollBar {
1158+
-ms-overflow-style: none;
1159+
scrollbar-width: none;
1160+
}
1161+
.hideScrollBar::-webkit-scrollbar {
1162+
display: none;
1163+
}
1164+
1165+
.preload * {
1166+
-webkit-transition: none !important;
1167+
-moz-transition: none !important;
1168+
-ms-transition: none !important;
1169+
-o-transition: none !important;
1170+
}

src/assets/baidu_logo.svg

Lines changed: 1 addition & 0 deletions
Loading

src/assets/bing_logo.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)