From 9dafbe81096cafadd2dca3fb3d123378460dc508 Mon Sep 17 00:00:00 2001
From: Kechicode <186776112+Kechicode@users.noreply.github.com>
Date: Tue, 7 Jan 2025 17:42:28 +0800
Subject: [PATCH 1/6] feat(Channel): Add SingleLine component to MainFeed with
dynamic channel links
---
src/views/Home/Channel/SingleLine/index.tsx | 78 ++++++++++
.../Home/Channel/SingleLine/styles.module.css | 32 ++++
src/views/Home/Feed/MainFeed/index.tsx | 147 ++++++++++++++++++
3 files changed, 257 insertions(+)
create mode 100644 src/views/Home/Channel/SingleLine/index.tsx
create mode 100644 src/views/Home/Channel/SingleLine/styles.module.css
diff --git a/src/views/Home/Channel/SingleLine/index.tsx b/src/views/Home/Channel/SingleLine/index.tsx
new file mode 100644
index 0000000000..d3a4fcb1a3
--- /dev/null
+++ b/src/views/Home/Channel/SingleLine/index.tsx
@@ -0,0 +1,78 @@
+import classnames from 'classnames'
+import { useState } from 'react'
+import { useEffect } from 'react'
+
+import styles from './styles.module.css'
+
+type SingleLineProps = {
+ items: {
+ id: string
+ title: string
+ link: string
+ }[]
+}
+
+const SingleLine = ({ items }: SingleLineProps) => {
+ const [hash, setHash] = useState('')
+
+ useEffect(() => {
+ // Function to update the hash state
+ const updateHash = () => {
+ setHash(window.location.hash)
+ }
+
+ // Set the initial hash
+ updateHash()
+
+ // Add an event listener to update the hash when it changes
+ window.addEventListener('hashchange', updateHash)
+
+ // Clean up the event listener on component unmount
+ return () => {
+ window.removeEventListener('hashchange', updateHash)
+ }
+ }, [])
+
+ const [selectedChannel, setSelectedChannel] = useState(1)
+
+ useEffect(() => {
+ if (hash) {
+ const channel = parseInt(hash.split('=')[1], 10)
+ setSelectedChannel(channel)
+
+ // scroll to the selected channel
+ const selectedChannel = document.querySelector(
+ `.singleLine-item[data-channel-id="${channel}"]`
+ )
+ if (selectedChannel) {
+ selectedChannel.scrollIntoView({
+ behavior: 'smooth',
+ inline: 'center',
+ block: 'nearest',
+ })
+ }
+ }
+ }, [hash])
+
+ return (
+
+ )
+}
+
+export default SingleLine
diff --git a/src/views/Home/Channel/SingleLine/styles.module.css b/src/views/Home/Channel/SingleLine/styles.module.css
new file mode 100644
index 0000000000..32383132e2
--- /dev/null
+++ b/src/views/Home/Channel/SingleLine/styles.module.css
@@ -0,0 +1,32 @@
+/* 频道行样式 */
+.singleLine {
+ @mixin border-bottom-grey;
+
+ position: relative;
+ display: flex;
+ gap: var(--sp12);
+ align-items: center;
+ margin: 0 calc(var(--sp16) * -1);
+ overflow-x: auto; /* horizontal scroll */
+ white-space: nowrap;
+ border-bottom-color: var(--color-grey-hover);
+ scrollbar-width: none; /* Firefox hide scrollbar */
+
+ &::-webkit-scrollbar {
+ display: none;
+ }
+
+ & .item {
+ flex-shrink: 0; /* prevent shrink */
+ padding: 8px 10px;
+ color: var(--color-grey-darker);
+ white-space: nowrap;
+ cursor: pointer;
+
+ &.selectedChannel {
+ font-weight: 600;
+ color: var(--color-black);
+ border-bottom: 1px solid var(--color-black);
+ }
+ }
+}
diff --git a/src/views/Home/Feed/MainFeed/index.tsx b/src/views/Home/Feed/MainFeed/index.tsx
index 74a9aa0056..0a61aa99b1 100644
--- a/src/views/Home/Feed/MainFeed/index.tsx
+++ b/src/views/Home/Feed/MainFeed/index.tsx
@@ -22,6 +22,7 @@ import {
import Announcements from '../../Announcements'
import ChannelCarousel from '../../Channel/Page/Carousel'
+import SingleLine from '../../Channel/SingleLine'
import Authors from '../Authors'
import Billboard from '../Billboard'
import { FEED_ARTICLES_PRIVATE, FEED_ARTICLES_PUBLIC } from '../gql'
@@ -89,6 +90,151 @@ const MainFeed = ({ feedSortType: sortBy }: MainFeedProps) => {
const viewer = useContext(ViewerContext)
const isHottestFeed = sortBy === 'hottest'
const isIcymiFeed = sortBy === 'icymi'
+
+ const host = typeof window !== 'undefined' ? window.location.origin : ''
+
+ const items = [
+ {
+ id: '1',
+ title: 'Item 1',
+ link: `${host}/#channel=1`,
+ },
+ {
+ id: '2',
+ title: 'Item 2',
+ link: `${host}/#channel=2`,
+ },
+ {
+ id: '3',
+ title: 'Item 3',
+ link: `${host}/#channel=3`,
+ },
+ {
+ id: '4',
+ title: 'Item 4',
+ link: `${host}/#channel=4`,
+ },
+ {
+ id: '5',
+ title: 'Item 5',
+ link: `${host}/#channel=5`,
+ },
+ {
+ id: '6',
+ title: 'Item 6',
+ link: `${host}/#channel=6`,
+ },
+ {
+ id: '7',
+ title: 'Item 7',
+ link: `${host}/#channel=7`,
+ },
+ {
+ id: '8',
+ title: 'Item 8',
+ link: `${host}/#channel=8`,
+ },
+ {
+ id: '9',
+ title: 'Item 9',
+ link: `${host}/#channel=9`,
+ },
+ {
+ id: '10',
+ title: 'Item 10',
+ link: `${host}/#channel=10`,
+ },
+ {
+ id: '11',
+ title: 'Item 11',
+ link: `${host}/#channel=11`,
+ },
+ {
+ id: '12',
+ title: 'Item 12',
+ link: `${host}/#channel=12`,
+ },
+ {
+ id: '13',
+ title: 'Item 13',
+ link: `${host}/#channel=13`,
+ },
+ {
+ id: '14',
+ title: 'Item 14',
+ link: `${host}/#channel=14`,
+ },
+ {
+ id: '15',
+ title: 'Item 15',
+ link: `${host}/#channel=15`,
+ },
+ {
+ id: '16',
+ title: 'Item 16',
+ link: `${host}/#channel=16`,
+ },
+ {
+ id: '17',
+ title: 'Item 17',
+ link: `${host}/#channel=17`,
+ },
+ {
+ id: '18',
+ title: 'Item 18',
+ link: `${host}/#channel=18`,
+ },
+ {
+ id: '19',
+ title: 'Item 19',
+ link: `${host}/#channel=19`,
+ },
+ {
+ id: '20',
+ title: 'Item 20',
+ link: `${host}/#channel=20`,
+ },
+ {
+ id: '21',
+ title: 'Item 21',
+ link: `${host}/#channel=21`,
+ },
+ {
+ id: '22',
+ title: 'Item 22',
+ link: `${host}/#channel=22`,
+ },
+ {
+ id: '23',
+ title: 'Item 23',
+ link: `${host}/#channel=23`,
+ },
+ {
+ id: '24',
+ title: 'Item 24',
+ link: `${host}/#channel=24`,
+ },
+ {
+ id: '25',
+ title: 'Item 25',
+ link: `${host}/#channel=25`,
+ },
+ {
+ id: '26',
+ title: 'Item 26',
+ link: `${host}/#channel=26`,
+ },
+ {
+ id: '27',
+ title: 'Item 27',
+ link: `${host}/#channel=27`,
+ },
+ {
+ id: '28',
+ title: 'Item 28',
+ link: `${host}/#channel=28`,
+ },
+ ]
/**
* Data Fetching
*/
@@ -218,6 +364,7 @@ const MainFeed = ({ feedSortType: sortBy }: MainFeedProps) => {
+
{isHottestFeed && }
{mixFeed.map((edge, i) => {
From 8fe8233c417e0f59012084c17043dbca6ff0ccea Mon Sep 17 00:00:00 2001
From: Kechicode <186776112+Kechicode@users.noreply.github.com>
Date: Tue, 7 Jan 2025 17:45:50 +0800
Subject: [PATCH 2/6] feat(Channel): refactor ChannelCarousel to Accept Dynamic
Items as Props
---
.../Home/Channel/Page/Carousel/index.tsx | 153 ++----------------
src/views/Home/Feed/MainFeed/index.tsx | 2 +-
2 files changed, 10 insertions(+), 145 deletions(-)
diff --git a/src/views/Home/Channel/Page/Carousel/index.tsx b/src/views/Home/Channel/Page/Carousel/index.tsx
index 1df7611b24..470305e85c 100644
--- a/src/views/Home/Channel/Page/Carousel/index.tsx
+++ b/src/views/Home/Channel/Page/Carousel/index.tsx
@@ -16,150 +16,15 @@ import styles from './styles.module.css'
type ColumnCount = '4' | '5' | '6' | '7'
-const ChannelCarousel = () => {
- const host = typeof window !== 'undefined' ? window.location.origin : ''
- const items = [
- {
- id: '1',
- title: 'Item 1',
- link: `${host}/#channel=1`,
- },
- {
- id: '2',
- title: 'Item 2',
- link: `${host}/#channel=2`,
- },
- {
- id: '3',
- title: 'Item 3',
- link: `${host}/#channel=3`,
- },
- {
- id: '4',
- title: 'Item 4',
- link: `${host}/#channel=4`,
- },
- {
- id: '5',
- title: 'Item 5',
- link: `${host}/#channel=5`,
- },
- {
- id: '6',
- title: 'Item 6',
- link: `${host}/#channel=6`,
- },
- {
- id: '7',
- title: 'Item 7',
- link: `${host}/#channel=7`,
- },
- {
- id: '8',
- title: 'Item 8',
- link: `${host}/#channel=8`,
- },
- {
- id: '9',
- title: 'Item 9',
- link: `${host}/#channel=9`,
- },
- {
- id: '10',
- title: 'Item 10',
- link: `${host}/#channel=10`,
- },
- {
- id: '11',
- title: 'Item 11',
- link: `${host}/#channel=11`,
- },
- {
- id: '12',
- title: 'Item 12',
- link: `${host}/#channel=12`,
- },
- {
- id: '13',
- title: 'Item 13',
- link: `${host}/#channel=13`,
- },
- {
- id: '14',
- title: 'Item 14',
- link: `${host}/#channel=14`,
- },
- {
- id: '15',
- title: 'Item 15',
- link: `${host}/#channel=15`,
- },
- {
- id: '16',
- title: 'Item 16',
- link: `${host}/#channel=16`,
- },
- {
- id: '17',
- title: 'Item 17',
- link: `${host}/#channel=17`,
- },
- {
- id: '18',
- title: 'Item 18',
- link: `${host}/#channel=18`,
- },
- {
- id: '19',
- title: 'Item 19',
- link: `${host}/#channel=19`,
- },
- {
- id: '20',
- title: 'Item 20',
- link: `${host}/#channel=20`,
- },
- {
- id: '21',
- title: 'Item 21',
- link: `${host}/#channel=21`,
- },
- {
- id: '22',
- title: 'Item 22',
- link: `${host}/#channel=22`,
- },
- {
- id: '23',
- title: 'Item 23',
- link: `${host}/#channel=23`,
- },
- {
- id: '24',
- title: 'Item 24',
- link: `${host}/#channel=24`,
- },
- {
- id: '25',
- title: 'Item 25',
- link: `${host}/#channel=25`,
- },
- {
- id: '26',
- title: 'Item 26',
- link: `${host}/#channel=26`,
- },
- {
- id: '27',
- title: 'Item 27',
- link: `${host}/#channel=27`,
- },
- {
- id: '28',
- title: 'Item 28',
- link: `${host}/#channel=28`,
- },
- ]
+type ChannelCarouselProps = {
+ items: {
+ id: string
+ title: string
+ link: string
+ }[]
+}
+
+const ChannelCarousel = ({ items }: ChannelCarouselProps) => {
const [dot, setDot] = useState(0)
const [, setSnaps] = useState([])
const [carousel, carouselApi] = useEmblaCarousel({
diff --git a/src/views/Home/Feed/MainFeed/index.tsx b/src/views/Home/Feed/MainFeed/index.tsx
index 0a61aa99b1..66e1ccf267 100644
--- a/src/views/Home/Feed/MainFeed/index.tsx
+++ b/src/views/Home/Feed/MainFeed/index.tsx
@@ -363,7 +363,7 @@ const MainFeed = ({ feedSortType: sortBy }: MainFeedProps) => {
>
-
+
{isHottestFeed && }
From 9c7b48b2418662a8526080adb142ea72617d0163 Mon Sep 17 00:00:00 2001
From: Kechicode <186776112+Kechicode@users.noreply.github.com>
Date: Tue, 7 Jan 2025 18:08:16 +0800
Subject: [PATCH 3/6] feat(MainFeed): Add dynamic single line display in
MainFeed
---
src/views/Home/Channel/Page/Carousel/index.tsx | 4 +++-
src/views/Home/Feed/MainFeed/index.tsx | 16 ++++++++++++++--
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/views/Home/Channel/Page/Carousel/index.tsx b/src/views/Home/Channel/Page/Carousel/index.tsx
index 470305e85c..a67b5cbe17 100644
--- a/src/views/Home/Channel/Page/Carousel/index.tsx
+++ b/src/views/Home/Channel/Page/Carousel/index.tsx
@@ -174,7 +174,9 @@ const ChannelCarousel = ({ items }: ChannelCarouselProps) => {