Skip to content

Commit

Permalink
Refactor Byline and Section for navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewTurk247 committed Jan 1, 2024
1 parent 99ab2a2 commit 2f4b3c1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 21 deletions.
13 changes: 9 additions & 4 deletions components/common/Byline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import { TouchableOpacity, StyleSheet, View } from "react-native";

import { Spacing, Sections } from "../../utils/constants";

const includesDesks = (category) => {
return category.desks && Object.keys(category.desks).length > 0;
};

export default function Byline({ authors, section, sourceName, category, date, navigation }) {
const entries = Object.entries(authors);
const bylineFontSize = entries.length < 3 ? 16 : 14;
const richCategory = Object.values(Sections).find((item) => item.id === category.id) ?? category;
const richCategory = Object.values(Sections).find((value) => value.id === category.id) ?? category;
const resolvedCategory = [3, 23, 25].includes(category.id) && includesDesks(richCategory) ? richCategory : category;

const Name = ({ detail }) => (
<TouchableOpacity onPress={() => navigation.navigate("Author", { name: detail[0], id: detail[1] })}>
Expand Down Expand Up @@ -42,10 +47,10 @@ export default function Byline({ authors, section, sourceName, category, date, n

<Button
onPress={() => {
if (richCategory?.name === sourceName) {
navigation.navigate("Section", { category: richCategory, seed: [] });
if (category.name === sourceName) {
navigation.navigate("Section", { category: resolvedCategory, seed: [] });
} else {
navigation.push("Section", { category: richCategory, seed: [] });
navigation.push("Section", { category: resolvedCategory, seed: [] });
}
}}
style={{ maxHeight: 100 }}
Expand Down
41 changes: 24 additions & 17 deletions components/screens/Section.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Model from "../../utils/model";
import Wildcard from "../common/Wildcard";

const BATCH_SIZE = 16;
const MemoizedWildcard = React.memo(Wildcard);
const SECTION_ALL = -1; // Special value for the union of all desks in a section or all articles in the section.

/**
* The `Section` screen displays a list of articles from a specific category.
Expand All @@ -23,9 +23,9 @@ const MemoizedWildcard = React.memo(Wildcard);
* - `possiblyReachedEnd`: A Boolean indicating whether all possible articles from the WordPress category have been fetched.
*
* @component
* @property {Object} route The route prop passed by the navigation. It includes the category and seed data.
* @property {{ category: import("../../utils/constants").Category, seed: Array<import("../../utils/model").WordPressPost> }} route.params The parameters passed by the navigation. It includes the category and seed data.
* @property {Object} navigation From React Navigation.
* @property {Object} route - The route prop passed by the navigation. It includes the category and seed data.
* @property {{ category: import("../../utils/constants").Category, seed: Array<import("../../utils/model").WordPressPost> }} route.params - The parameters passed by the navigation. It includes the category and seed data.
* @property {Object} navigation - From React Navigation.
* @exports Section
*/
export default function Section({ route, navigation }) {
Expand All @@ -39,18 +39,30 @@ export default function Section({ route, navigation }) {
const scrollViewRef = useRef(null);
const tabWidths = useRef(new Array(category.desks?.length ?? 1).fill(0));

// Measure the width of each tab.
const measureTab = (index) => (event) => {
const { width } = event.nativeEvent.layout;
tabWidths.current[index] = width;
};

// Calculate the position of the tab.
/**
* Calculates the position of the tab.
* When a tab is selected, this function calculates its position (i.e., its offset from the start of the `ScrollView`).
* This can be done by taking the sum of the widths of all tabs before the selected one.
* @function
* @param {number} index - The index of the selected tab.
* @returns {number} The position of the tab.
*/
const getTabOffset = (index) => {
return tabWidths.current.slice(0, index).reduce((acc, width) => acc + width, 0);
};

// Scroll to the selected tab if it is not currently visible.
/**
* Determines the position of the selected tab within the `ScrollView` and then uses the `scrollTo` method to adjust the scroll position accordingly.
* Checks if the selected tab is fully visible within the `ScrollView` by comparing the tab's position and the current scroll position of the `ScrollView`.
* If the tab is not fully visible, this function uses the `scrollTo` method of the `ScrollView` to adjust the scroll position so that the selected tab becomes visible.
* @function
* @param {number} index - The index of the selected tab.
*/
const scrollToSelectedTab = (index) => {
const offset = getTabOffset(index);
scrollViewRef?.current?.scrollTo({ x: offset, animated: true });
Expand Down Expand Up @@ -109,12 +121,7 @@ export default function Section({ route, navigation }) {
onEndReached={loadMoreArticles}
onEndReachedThreshold={0.5}
renderItem={({ item, index }) => (
<MemoizedWildcard
key={`${subcategory.id}-${item.id}`}
item={item}
index={index}
navigation={navigation}
/>
<Wildcard key={`${subcategory.id}-${item.id}`} item={item} index={index} navigation={navigation} />
)}
ListFooterComponent={() => articlesLoading && <ActivityIndicator />}
/>
Expand All @@ -126,7 +133,7 @@ export default function Section({ route, navigation }) {

const renderTabs = () => {
const tabs = [
{ name: `All ${category.name}`, id: "all" },
{ name: `All ${category.name}`, id: SECTION_ALL },
...Object.values(category.desks ?? {}).map((desk, index) => ({ ...desk, id: index + 1 })),
];

Expand All @@ -147,12 +154,12 @@ export default function Section({ route, navigation }) {
};

const renderPagerView = () => {
const sections = [{ ...category, id: "all" }, ...Object.values(category.desks ?? {})];
const sections = [{ ...category, id: SECTION_ALL }, ...Object.values(category.desks ?? {})];

return sections.map((section) => {
const numericId = section.id === "all" ? category.id : section.id;
const numericId = section.id === SECTION_ALL ? category.id : section.id;
const subcategory =
section.id === "all"
section.id === SECTION_ALL
? category
: Object.values(category.desks).find((value) => value.id === section.id) ?? category;
const filteredSeed = seed.filter((item) => item.categories.includes(numericId));
Expand Down

0 comments on commit 2f4b3c1

Please sign in to comment.