Skip to content

Commit

Permalink
Web UI refresh (#524)
Browse files Browse the repository at this point in the history
  • Loading branch information
duogenesis authored Dec 24, 2024
1 parent 45f43a0 commit 3c6d113
Show file tree
Hide file tree
Showing 18 changed files with 1,048 additions and 108 deletions.
9 changes: 7 additions & 2 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import * as ScreenOrientation from 'expo-screen-orientation';
import * as SplashScreen from 'expo-splash-screen';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

import { TabBar } from './components/tab-bar';
import { TabBar } from './components/navigation/tab-bar';
import SearchTab from './components/search-tab';
import { QuizTab } from './components/quiz-tab';
import ProfileTab from './components/profile-tab';
Expand Down Expand Up @@ -58,14 +58,19 @@ import { ClubItem } from './club/club';
import { Toast } from './components/toast';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { DonationNagModal } from './components/donation-nag-modal';
import { createWebNavigator } from './components/navigation/web-navigator';
import { isMobile } from './util/util';


// TODO: Onboarding works

setNofications();
verificationWatcher();

SplashScreen.preventAutoHideAsync();

const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
const Tab = isMobile() ? createBottomTabNavigator() : createWebNavigator();

if (
Platform.OS === 'android' &&
Expand Down
2 changes: 1 addition & 1 deletion components/conversation-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,6 @@ const TextInputWithButton = ({
backgroundColor: 'rgb(228, 204, 255)',
borderRadius: 999,
borderWidth: 1,
borderBottomWidth: 3,
borderColor: '#70f',
opacity: opacity,
}}
Expand Down Expand Up @@ -882,6 +881,7 @@ const styles = StyleSheet.create({
textInput: {
backgroundColor: '#eee',
borderRadius: 10,
borderWidth: 0,
padding: 10,
fontSize: 16,
flex: 1,
Expand Down
26 changes: 21 additions & 5 deletions components/default-flat-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,6 @@ type DefaultFlatListProps<ItemT> =
| "ListEmptyComponent"
| "ListFooterComponent"
| "data"
| "onContentSizeChange"
| "onLayout"
| "onRefresh"
| "refreshing"
>;
Expand Down Expand Up @@ -343,10 +341,18 @@ const DefaultFlatList = forwardRef(<ItemT,>(props: DefaultFlatListProps<ItemT>,
if (contentHeight.current < viewportHeight.current) {
fetchNextPage();
}

if (props.onContentSizeChange) {
props.onContentSizeChange(width, height);
}
};

const onLayout = useCallback(({ nativeEvent: { layout: { height } } }) => {
viewportHeight.current = height;
const onLayout = useCallback((params) => {
viewportHeight.current = params.nativeEvent.layout.height;

if (props.onLayout) {
props.onLayout(params);
}
}, []);

if (props.contentContainerStyle !== contentContainerStyle[1]) {
Expand All @@ -361,7 +367,17 @@ const DefaultFlatList = forwardRef(<ItemT,>(props: DefaultFlatListProps<ItemT>,

return (
<FlatList
ref={flatList}
ref={(node) => {
flatList.current = node;

if (props.innerRef === undefined) {
;
} else if (typeof props.innerRef === 'function') {
props.innerRef(node);
} else {
props.innerRef.current = node;
}
}}
refreshing={false}
onRefresh={props.disableRefresh ? undefined : onRefresh}
onEndReachedThreshold={props.onEndReachedThreshold ?? 1}
Expand Down
16 changes: 16 additions & 0 deletions components/inbox-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { inboxOrder, inboxSection } from '../kv-storage/inbox';
import { signedInUser } from '../App';
import { Notice } from './notice';
import { listen, lastEvent } from '../events/events';
import { useScrollbar } from './navigation/scroll-bar-hooks';


const Stack = createNativeStackNavigator();

Expand Down Expand Up @@ -297,6 +299,14 @@ const InboxTab = ({navigation}) => {

const keyExtractor = useCallback((c: Conversation) => JSON.stringify(c), []);

const {
onLayout,
onContentSizeChange,
onScroll,
showsVerticalScrollIndicator,
observeListRef,
} = useScrollbar('inbox');

return (
<SafeAreaView style={styles.safeAreaView}>
<InboxTabNavBar
Expand All @@ -311,6 +321,7 @@ const InboxTab = ({navigation}) => {
{inbox !== null &&
<DefaultFlatList
ref={listRef}
innerRef={observeListRef}
emptyText={emptyText}
endText={endText}
fetchPage={fetchPage}
Expand All @@ -320,6 +331,10 @@ const InboxTab = ({navigation}) => {
renderItem={renderItem}
keyExtractor={keyExtractor}
disableRefresh={true}
onLayout={onLayout}
onContentSizeChange={onContentSizeChange}
onScroll={onScroll}
showsVerticalScrollIndicator={showsVerticalScrollIndicator}
/>
}
</SafeAreaView>
Expand Down Expand Up @@ -364,6 +379,7 @@ const InboxTabNavBar = ({
iconName={showArchive ? 'chatbubbles-outline' : 'file-tray-full-outline'}
position="right"
secondary={false}
label={showArchive ? "Inbox" : "Archive"}
/>
</TopNavBar>
);
Expand Down
140 changes: 140 additions & 0 deletions components/navigation/scroll-bar-hooks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import {
useEffect,
useRef,
} from 'react';
import {
isMobile,
} from '../../util/util';
import { findDOMNode } from 'react-dom';
import { notify } from '../../events/events';
import { ScrollViewData } from '../navigation/scroll-bar';

const useScrollbar = (controller: string) => {
const observer = useRef<IntersectionObserver | null>(null);

const lastScrollViewHeight = useRef(0);
const lastContentHeight = useRef(0);
const lastOffset = useRef(0);

useEffect(() => {
if (isMobile()) {
return;
}

return () => {
if (observer.current) {
observer.current.disconnect();
observer.current = null;
}
}
}, []);

return useRef({
onLayout: (params) => {
if (isMobile()) {
return;
}

lastScrollViewHeight.current = params.nativeEvent.layout.height;

notify<ScrollViewData>(
'main-scroll-view',
{
controller,
scrollViewHeight: lastScrollViewHeight.current,
contentHeight: lastContentHeight.current,
offset: lastOffset.current,
}
);
},
onContentSizeChange: (contentWidth, contentHeight) => {
if (isMobile()) {
return;
}

lastContentHeight.current = contentHeight;

notify<ScrollViewData>(
'main-scroll-view',
{
controller,
scrollViewHeight: lastScrollViewHeight.current,
contentHeight: lastContentHeight.current,
offset: lastOffset.current,
}
);
},
onScroll: ({nativeEvent}) => {
if (isMobile()) {
return;
}

lastOffset.current = nativeEvent.contentOffset.y;

notify<ScrollViewData>(
'main-scroll-view',
{
controller,
offset: lastOffset.current,
}
)
},
showsVerticalScrollIndicator: isMobile(),
observeListRef: (node): void => {
if (isMobile()) {
return;
}
if (!node) {
return;
}

if (observer.current) {
observer.current.disconnect();
}

const onThumbDrag = (offset: number) => {
if (typeof node.scrollToOffset === 'function') {
node.scrollToOffset({ offset, animated: false });
} else if (typeof node.scrollTo === 'function') {
node.scrollTo({ y: offset, animated: false });
} else {
throw new Error('No scroll method found on ref');
}
};

observer.current = new IntersectionObserver(
([entry]) => {
if (!entry.isIntersecting) {
notify<ScrollViewData>(
'main-scroll-view',
{
controller,
onThumbDrag: null,
}
);

return;
}

notify<ScrollViewData>(
'main-scroll-view',
{
controller,
scrollViewHeight: lastScrollViewHeight.current,
contentHeight: lastContentHeight.current,
offset: lastOffset.current,
onThumbDrag: onThumbDrag,
}
);
},
{ root: null }
);

observer.current.observe(findDOMNode(node));
}
}).current;
};

export {
useScrollbar,
};
Loading

0 comments on commit 3c6d113

Please sign in to comment.