Skip to content

Commit 93daa1e

Browse files
committed
improve the pause mode display
1 parent 4fac2ae commit 93daa1e

10 files changed

Lines changed: 172 additions & 109 deletions

File tree

src/App.js

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
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, PausedAppContent } 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 intersectionOptions = {
19+
threshold: 0.5,
20+
}
21+
1822
function App() {
1923
const [showSideBar, setShowSideBar] = useState(false)
2024
const [showSettings, setShowSettings] = useState(false)
@@ -24,7 +28,7 @@ function App() {
2428
firstSeenDate,
2529
markOnboardingAsCompleted,
2630
maxVisibleCards,
27-
pauseTo,
31+
isPauseModeActive,
2832
} = useUserPreferences()
2933

3034
useLayoutEffect(() => {
@@ -47,15 +51,34 @@ function App() {
4751
trackPageView('home')
4852
}, [])
4953

50-
const isAppPaused = Boolean(pauseTo && pauseTo - new Date().getTime() > 0)
51-
console.log('pauseTo: ', isAppPaused)
54+
let callback = (entries) => {
55+
entries.forEach((entry) => {
56+
if (!entry.isIntersecting) {
57+
document.documentElement.classList.remove('dndState')
58+
} else {
59+
document.documentElement.classList.add('dndState')
60+
}
61+
})
62+
}
63+
64+
useLayoutEffect(() => {
65+
let dndLayoutDiv = document.getElementsByClassName('pauseContentWrapper')[0]
66+
let observer = new IntersectionObserver(callback, intersectionOptions)
67+
68+
if (dndLayoutDiv) {
69+
observer.observe(dndLayoutDiv)
70+
}
71+
72+
return () => {
73+
observer.disconnect()
74+
}
75+
}, [])
5276

5377
return (
5478
<>
5579
<MarketingBanner />
5680

5781
<div className="App">
58-
<PausedAppContent isAppPaused={isAppPaused} />
5982
{!onboardingCompleted && isWebOrExtensionVersion() === 'extension' && (
6083
<Suspense fallback={null}>
6184
<OnboardingModal
@@ -70,8 +93,11 @@ function App() {
7093
showSettings={showSettings}
7194
setShowSettings={setShowSettings}
7295
/>
73-
<ScrollCardsNavigator />
74-
<AppContentLayout setShowSettings={setShowSettings} />
96+
97+
<div className="layoutLayers hideScrollBar">
98+
{isPauseModeActive() && <DNDLayout />}
99+
<AppContentLayout setShowSettings={setShowSettings} />
100+
</div>
75101
<BookmarksSidebar showSidebar={showSideBar} onClose={() => setShowSideBar(false)} />
76102
</div>
77103
</>

src/assets/App.css

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
html {
44
background: var(--background-color);
55
scroll-behavior: smooth;
6+
overflow: hidden;
67
}
78
body {
89
color: var(--primary-text-color);
@@ -36,6 +37,7 @@ a {
3637
color: var(--primary-text-color);
3738
display: flex;
3839
flex-direction: column;
40+
height: 100vh;
3941
}
4042
.errorMsg {
4143
text-align: center;
@@ -62,8 +64,11 @@ a {
6264
align-items: center;
6365
align-content: center;
6466
flex-wrap: wrap;
65-
height: 86px;
67+
height: 10vh;
6668
margin: 0.5% 1% 0px 1%;
69+
position: sticky;
70+
z-index: 1;
71+
top: 0;
6772
}
6873

6974
.AppFooter {
@@ -91,18 +96,19 @@ a {
9196

9297
.AppContent {
9398
position: relative;
94-
overflow-y: hidden;
95-
padding: 12px 0;
99+
margin: 0;
96100
}
97101
.Cards {
98-
padding: 1%;
99102
flex: 1 1 auto;
100103
display: flex;
101104
gap: 12px;
102105
position: relative;
103106
overflow-y: hidden;
107+
justify-content: space-between;
104108
scroll-snap-type: x mandatory;
105109
scroll-padding-left: 12px;
110+
padding-top: 2vh;
111+
height: 87vh;
106112
}
107113
.HorizontalScroll {
108114
-ms-overflow-style: none;
@@ -114,10 +120,7 @@ a {
114120

115121
.extras {
116122
flex-direction: row;
117-
margin-right: 16px;
118123
align-content: center;
119-
120-
transition: width, left, right, 0.3s;
121124
}
122125
.darkModeBtn {
123126
background-color: var(--dark-mode-background-color) !important;
@@ -140,6 +143,7 @@ a {
140143
display: inline-flex;
141144
align-items: center;
142145
justify-content: center;
146+
transition: all 0.4s linear;
143147
}
144148
.extraTextBtn {
145149
padding: 0 16px;
@@ -199,7 +203,7 @@ a {
199203
border-radius: 10px;
200204
overflow: hidden;
201205
flex-direction: column;
202-
height: 82vh;
206+
height: 98%;
203207
width: 10vw;
204208
flex: 0 0 auto;
205209
scroll-snap-align: start;
@@ -772,6 +776,7 @@ Producthunt item
772776
position: relative;
773777
margin: 0 auto;
774778
margin-top: 6px;
779+
transition: all 0.3s linear;
775780
}
776781
.searchBarIcon {
777782
position: absolute;
@@ -850,7 +855,7 @@ Producthunt item
850855

851856
.scrollButton {
852857
border: none;
853-
position: fixed;
858+
position: absolute;
854859
top: 45%;
855860
margin: 0 1%;
856861
background-color: var(--card-action-button-background);
@@ -1097,7 +1102,7 @@ Producthunt item
10971102
}
10981103
.block {
10991104
width: calc(
1100-
(1800px - 14px * min(5, var(--max-visible-cards))) / min(5, var(--max-visible-cards))
1105+
(1800px - 20px * min(5, var(--max-visible-cards))) / min(5, var(--max-visible-cards))
11011106
);
11021107
}
11031108
}
@@ -1125,54 +1130,36 @@ Producthunt item
11251130
position: relative;
11261131
vertical-align: middle;
11271132
}
1128-
1129-
/* PAUSE CONTENT */
1130-
.pauseContentWrapper {
1131-
height: 0;
1132-
transition: height 0.5s ease-out;
1133-
}
1134-
1135-
.pauseContentWrapper.active {
1133+
.layoutLayers {
1134+
scroll-snap-type: y mandatory;
1135+
display: flex;
1136+
flex-direction: column;
11361137
height: 100vh;
1138+
overflow-y: scroll;
1139+
margin: 0 1%;
11371140
}
1138-
1139-
.pauseContentWrapper .options {
1140-
height: 5%;
1141-
display: flex;
1142-
justify-content: flex-end;
1143-
align-items: flex-end;
1144-
padding-right: 24px;
1141+
.layoutLayers > * {
1142+
scroll-snap-align: end;
11451143
}
11461144

1147-
.pauseContentWrapper .searchContainer {
1148-
height: 95%;
1149-
display: flex;
1150-
justify-content: center;
1151-
align-items: center;
1152-
}
1153-
1154-
.searchBarWithLogo {
1155-
display: flex;
1156-
flex-direction: column;
1157-
row-gap: 24px;
1158-
align-items: center;
1159-
align-content: center;
1145+
.tags {
1146+
transition: visibility 0.3s ease-out, opacity 0.3s ease-in;
1147+
visibility: visible;
1148+
opacity: 1;
11601149
}
11611150

1162-
.searchBarWithLogo .searchEngineLogo {
1163-
width: 280px;
1164-
height: 120px;
1165-
text-align: center;
1166-
margin: 0 auto;
1167-
}
1168-
.searchEngineLogo svg {
1169-
width: 100%;
1170-
height: 100%;
1171-
}
11721151
/*Helpers */
11731152
.noMargin {
11741153
margin: 0 !important;
11751154
}
11761155
.marginLeftAuto {
11771156
margin-left: auto;
11781157
}
1158+
1159+
.hideScrollBar {
1160+
-ms-overflow-style: none;
1161+
scrollbar-width: none;
1162+
}
1163+
.hideScrollBar::-webkit-scrollbar {
1164+
display: none;
1165+
}

src/components/Layout/AppContentLayout.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useState } from 'react'
22
import { isDesktop } from 'react-device-detect'
33
import { useUserPreferences } from 'src/stores/preferences'
44
import { BottomNavigation } from '../Elements'
5+
import { ScrollCardsNavigator } from './'
56
import { DesktopCards } from './DesktopCards'
67
import { MobileCards } from './MobileCards'
78

@@ -14,8 +15,9 @@ export const AppContentLayout = ({
1415
const [selectedCard, setSelectedCard] = useState(cards[0])
1516

1617
return (
17-
<>
18+
<section>
1819
<main className="AppContent">
20+
<ScrollCardsNavigator />
1921
{isDesktop ? (
2022
<DesktopCards cards={cards} userCustomCards={userCustomCards} />
2123
) : (
@@ -29,6 +31,6 @@ export const AppContentLayout = ({
2931
setSelectedCard={setSelectedCard}
3032
setShowSettings={setShowSettings}
3133
/>
32-
</>
34+
</section>
3335
)
3436
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
.dndState .AppHeader .searchBar {
2+
opacity: 0;
3+
transform: translate(0, 10px);
4+
transition: all 0.4s ease-out;
5+
}
6+
.dndState .tags {
7+
opacity: 0;
8+
transform: translate(0, 10px);
9+
filter: blur(2px);
10+
transition: all 0.4s ease-out;
11+
}
12+
13+
.pauseContentWrapper {
14+
min-height: 100%;
15+
display: flex;
16+
flex-direction: column;
17+
align-items: center;
18+
justify-content: center;
19+
}
20+
21+
.scrollToCardsLayout {
22+
display: flex;
23+
flex-direction: column;
24+
align-items: center;
25+
row-gap: 12px;
26+
font-size: 18px;
27+
border: none;
28+
background: none;
29+
color: var(--primary-text-color);
30+
cursor: pointer;
31+
padding: 20px 0;
32+
}
33+
34+
.scrollToCardsLayout:hover .icon {
35+
transform: translate(0, 10px);
36+
transition: transform 0.3s ease-in-out;
37+
animation-iteration-count: revert;
38+
}
39+
.scrollToCardsLayout .icon {
40+
transition: all 0.3s ease-in-out;
41+
font-size: 20px;
42+
}
43+
44+
.searchWidget {
45+
flex-grow: 1;
46+
display: flex;
47+
align-items: center;
48+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useLayoutEffect, useRef } from 'react'
2+
import { BsChevronDown } from 'react-icons/bs'
3+
import { SearchBarWithLogo } from 'src/components/Elements'
4+
import './DNDLayout.css'
5+
6+
export const DNDLayout = () => {
7+
const cardsLayoutContainer = useRef<HTMLElement | null>(null)
8+
9+
useLayoutEffect(() => {
10+
cardsLayoutContainer.current = document.querySelector('.AppContent')
11+
}, [])
12+
13+
const onScrollToCardsLayoutClicked = () => {
14+
if (!cardsLayoutContainer.current) {
15+
return
16+
}
17+
cardsLayoutContainer.current?.scrollIntoView({ behavior: 'smooth' })
18+
}
19+
20+
return (
21+
<section className="pauseContentWrapper">
22+
<div className="searchWidget">
23+
<SearchBarWithLogo />
24+
</div>
25+
26+
<button className="scrollToCardsLayout" onClick={() => onScrollToCardsLayoutClicked()}>
27+
Scroll for Dev News
28+
<BsChevronDown className="icon" />
29+
</button>
30+
</section>
31+
)
32+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./DNDLayout";

0 commit comments

Comments
 (0)