Skip to content

[#21902] Reimplement community overview #22293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Mar 26, 2025
Merged
295 changes: 295 additions & 0 deletions src/js/worklets/communities.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
import {
useDerivedValue,
useAnimatedStyle,
interpolate,
scrollTo,
withTiming,
cancelAnimation,
withDecay,
} from 'react-native-reanimated';

import { Platform } from 'react-native';

export function useLogoStyles({
scrollAmount,
expandHeaderThreshold,
sheetDisplacementThreshold,
textMovementThreshold,
}) {
return useAnimatedStyle(() => {
const firstDisplacement = scrollAmount.value < expandHeaderThreshold;
if (firstDisplacement) {
return {
transform: [
{ translateX: 20 },
{ translateY: interpolate(scrollAmount.value, [0, expandHeaderThreshold], [0, -42.5], 'clamp') },
{ scale: interpolate(scrollAmount.value, [0, textMovementThreshold], [1, 0.4], 'clamp') },
],
};
} else {
return {
transform: [
{ translateX: 20 },
{
translateY: interpolate(
scrollAmount.value,
[expandHeaderThreshold, sheetDisplacementThreshold],
[-42.5, -50.5],
'clamp',
),
},
{ scale: 0.4 },
],
};
}
});
}

export function useSheetStyles({ scrollAmount, expandHeaderThreshold, sheetDisplacementThreshold }) {
return useAnimatedStyle(() => {
const firstDisplacement = scrollAmount.value < expandHeaderThreshold;
if (firstDisplacement) {
return {
transform: [{ translateY: interpolate(scrollAmount.value, [0, expandHeaderThreshold], [40, 0], 'clamp') }],
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
};
} else {
const radius = interpolate(
scrollAmount.value,
[expandHeaderThreshold, sheetDisplacementThreshold],
[20, 0],
'clamp',
);
return {
transform: [
{
translateY: interpolate(
scrollAmount.value,
[expandHeaderThreshold, sheetDisplacementThreshold],
[0, -8],
'clamp',
),
},
],
borderTopLeftRadius: radius,
borderTopRightRadius: radius,
};
}
});
}

export function useNameStyles({ scrollAmount, expandHeaderThreshold, textMovementThreshold }) {
return useAnimatedStyle(() => {
const animationProgress = interpolate(
scrollAmount.value,
[textMovementThreshold, expandHeaderThreshold],
[0, 40],
'clamp',
);
return {
marginRight: animationProgress,
transform: [
{ translateX: animationProgress },
{
translateY: interpolate(
scrollAmount.value,
[textMovementThreshold, expandHeaderThreshold],
[0, -44.5],
'clamp',
),
},
],
};
});
}

export function useInfoStyles({ scrollAmount, infoOpacityThreshold }) {
return useAnimatedStyle(() => {
return {
opacity: interpolate(scrollAmount.value, [0, infoOpacityThreshold], [1, 0.2], 'extend'),
};
});
}

export function useChannelsStyles({
scrollAmount,
headerHeight,
expandHeaderThreshold,
sheetDisplacementThreshold,
expandHeaderLimit,
}) {
return useAnimatedStyle(() => {
const headerDisplacement = (headerHeight.value - 55.5) * -1;
const firstDisplacement = scrollAmount.value < expandHeaderThreshold;
const secondDisplacement = scrollAmount.value > sheetDisplacementThreshold;
if (firstDisplacement) {
return {
transform: [
{
translateY: interpolate(scrollAmount.value, [0, expandHeaderThreshold], [39, headerDisplacement], 'clamp'),
},
],
};
} else if (secondDisplacement) {
return {
transform: [
{
translateY: interpolate(
scrollAmount.value,
[sheetDisplacementThreshold, expandHeaderLimit],
[headerDisplacement - 8, headerDisplacement - 64],
'clamp',
),
},
],
};
} else {
return {
transform: [
{
translateY: interpolate(
scrollAmount.value,
[expandHeaderThreshold, sheetDisplacementThreshold],
[headerDisplacement, headerDisplacement - 8],
'clamp',
),
},
],
};
}
}, [headerHeight.value]);
}

export function useScrollTo({ animatedRef, scrollAmount, expandHeaderLimit }) {
const isAndroid = Platform.OS === 'android';
return useDerivedValue(() => {
scrollTo(animatedRef, 0, scrollAmount.value - expandHeaderLimit, isAndroid);
});
}

export function useHeaderOpacity({ scrollAmount, expandHeaderThreshold, sheetDisplacementThreshold }) {
return useDerivedValue(() => {
return interpolate(scrollAmount.value, [expandHeaderThreshold, sheetDisplacementThreshold], [0, 1], 'clamp');
});
}

export function useOppositeHeaderOpacity(headerOpacity) {
return useDerivedValue(() => {
return 1 - headerOpacity.value;
});
}

export function useNavContentOpacity({ scrollAmount, sheetDisplacementThreshold, expandHeaderLimit }) {
return useDerivedValue(() => {
return interpolate(scrollAmount.value, [sheetDisplacementThreshold, expandHeaderLimit], [0, 1], 'clamp');
});
}

export function onScrollAnimationEnd(
scrollAmount,
scrollStart,
expandHeaderThreshold,
snapHeaderThreshold,
expandHeaderLimit,
animationDuration,
) {
'worklet';
return function () {
'worklet';
const duration = { duration: animationDuration };
if (scrollAmount.value > snapHeaderThreshold && scrollAmount.value <= expandHeaderThreshold) {
scrollStart.value = withTiming(-expandHeaderThreshold, duration);
scrollAmount.value = withTiming(expandHeaderThreshold, duration);
}

if (scrollAmount.value > expandHeaderThreshold) {
scrollStart.value = -scrollAmount.value;
}

if (scrollAmount.value <= snapHeaderThreshold) {
scrollStart.value = withTiming(0, duration);
scrollAmount.value = withTiming(0, duration);
}

if (scrollAmount.value > expandHeaderThreshold && scrollAmount.value < expandHeaderLimit) {
if (scrollAmount.value >= (expandHeaderLimit - expandHeaderThreshold) * 0.65 + expandHeaderThreshold) {
scrollAmount.value = withTiming(expandHeaderLimit, duration);
scrollStart.value = withTiming(-expandHeaderLimit, duration);
} else {
scrollAmount.value = withTiming(expandHeaderThreshold, duration);
scrollStart.value = withTiming(-expandHeaderThreshold, duration);
}
}
};
}

export function onPanStart(scrollStart, scrollAmount) {
return function () {
'worklet';
cancelAnimation(scrollStart);
cancelAnimation(scrollAmount);
scrollStart.value = -1 * scrollAmount.value;
};
}

export function onPanUpdate({ scrollStart, scrollAmount, maxScroll, expandHeaderLimit }) {
return function (event) {
'worklet';
const newScrollAmount = -1 * (event.translationY + scrollStart.value);
if (newScrollAmount <= 0) {
scrollAmount.value = 0;
} else {
const limit = expandHeaderLimit + maxScroll.value;
scrollAmount.value = newScrollAmount <= limit ? newScrollAmount : limit;
}
};
}

export function onPanEnd({
scrollStart,
scrollAmount,
maxScroll,
expandHeaderLimit,
expandHeaderThreshold,
snapHeaderThreshold,
animationDuration,
}) {
const isIOS = Platform.OS === 'ios';
return function (event) {
'worklet';
scrollStart.value = -scrollAmount.value;
const endAnimation = onScrollAnimationEnd(
scrollAmount,
scrollStart,
expandHeaderThreshold,
snapHeaderThreshold,
expandHeaderLimit,
animationDuration,
);
if (scrollAmount.value < expandHeaderLimit) {
endAnimation();
} else {
const maxValue = maxScroll.value + expandHeaderLimit;
const decelerationRate = isIOS ? { deceleration: 0.9997 } : { deceleration: 0.999 };

scrollStart.value = withDecay({
...{
velocity: event.velocityY,
clamp: [-1 * maxValue, 0],
},
...decelerationRate,
});
scrollAmount.value = withDecay(
{
...{
velocity: -1 * event.velocityY,
clamp: [0, maxValue],
},
...decelerationRate,
},
endAnimation,
);
}
};
}
12 changes: 12 additions & 0 deletions src/mocks/js_dependencies.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,18 @@
(slurp
"./resources/data/emojis/en.json"))
"../src/js/worklets/core.js" worklet-factory
"../src/js/worklets/communities.js" #js {"useLogoStyles" #js {}
"useSheetStyles" #js {}
"useNameStyles" #js {}
"useInfoStyles" #js {}
"useChannelsStyles" #js {}
"useScrollTo" #js {}
"useHeaderOpacity" #js {}
"useOppositeHeaderOpacity" #js {}
"useNavContentOpacity" #js {}
"onPanStart" #js {}
"onPanUpdate" #js {}
"onPanEnd" #js {}}
"../src/js/worklets/shell/bottom_tabs.js" #js {}
"../src/js/worklets/shell/home_stack.js" #js {}
"../src/js/worklets/bottom_sheet.js" #js {}
Expand Down
11 changes: 5 additions & 6 deletions src/quo/components/navigation/page_nav/style.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@
{:width 12})

(defn right-content
[min-size?]
(merge
{:flex-grow 1
:flex-basis 1}
(when min-size?
{:min-height 32})))
[min-size? centered-content?]
(cond-> {}
centered-content? (assoc :flex-grow 1
:flex-basis 1)
min-size? (assoc :min-height 32)))

(def token-logo
{:width 16 :height 16})
Expand Down
22 changes: 12 additions & 10 deletions src/quo/components/navigation/page_nav/view.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@

(defn- right-content
[{:keys [background content max-actions min-size? support-account-switcher?
behind-overlay?]
:or {support-account-switcher? true}}]
[rn/view (style/right-content min-size?)
behind-overlay? centered-content?]
:or {support-account-switcher? true
centered-content? true}}]
[rn/view (style/right-content min-size? centered-content?)
(when (coll? content)
(into [rn/view {:style style/right-actions-container}]
(add-right-buttons-xf max-actions background behind-overlay? support-account-switcher?)
Expand Down Expand Up @@ -260,15 +261,15 @@
right-side :none
background :white}
:as props}]
(let [center-content-container-style (reanimated/apply-animations-to-style
(let [centered-content? (case type
:title (= text-align :center)
(:dropdown :wallet-networks) true
false)
center-content-container-style (reanimated/apply-animations-to-style
(if center-opacity
{:opacity center-opacity}
nil)
(style/center-content-container
(case type
:title (= text-align :center)
(:dropdown :wallet-networks) true
false)))
(style/center-content-container centered-content?))
props-with-style (assoc props
:center-content-container-style
center-content-container-style)]
Expand Down Expand Up @@ -342,6 +343,7 @@
{:background background
:content right-side
:max-actions 3
:support-account-switcher? false}]]
:support-account-switcher? false
:centered-content? centered-content?}]]

nil)))
Loading