mirror of
https://github.com/samuelthomas2774/nxapi.git
synced 2026-03-21 18:04:10 -05:00
Show friends relative last online time
This commit is contained in:
parent
9fa92fd6cc
commit
0d54381c6d
|
|
@ -8,7 +8,7 @@ import { getTitleIdFromEcUrl, hrduration } from '../../../util/misc.js';
|
|||
import { Button } from '../components/index.js';
|
||||
import { DEFAULT_ACCENT_COLOUR, TEXT_COLOUR_ACTIVE, TEXT_COLOUR_DARK, TEXT_COLOUR_LIGHT } from '../constants.js';
|
||||
import ipc, { events } from '../ipc.js';
|
||||
import { RequestState, Root, useAccentColour, useAsync, useColourScheme, useDiscordPresenceSource, useEventListener } from '../util.js';
|
||||
import { RequestState, Root, useAccentColour, useAsync, useColourScheme, useDiscordPresenceSource, useEventListener, useTimeSince } from '../util.js';
|
||||
|
||||
export interface FriendProps {
|
||||
user: string;
|
||||
|
|
@ -86,6 +86,8 @@ export default function Friend(props: FriendProps) {
|
|||
|
||||
<Text style={[styles.friendCreatedAt, theme.text]}>Friends since {new Date(friend.friendCreatedAt * 1000).toLocaleString('en-GB')}</Text>
|
||||
{friend.presence.updatedAt ? <Text style={[styles.presenceUpdatedAt, theme.text]}>Presence updated at {new Date(friend.presence.updatedAt * 1000).toLocaleString('en-GB')}</Text> : null}
|
||||
{!(friend.presence.state === PresenceState.ONLINE || friend.presence.state === PresenceState.PLAYING) &&
|
||||
friend.presence.logoutAt ? <Text style={[styles.presenceUpdatedAt, theme.text]}>Last online at {new Date(friend.presence.logoutAt * 1000).toLocaleString('en-GB')}</Text> : null}
|
||||
<Text style={[styles.canSeeUserPresence, theme.text]}>This user {can_see_user_presence ? 'can' : 'can not'} see your presence.</Text>
|
||||
</View>
|
||||
|
||||
|
|
@ -120,6 +122,7 @@ function FriendPresence(props: {
|
|||
const theme = useColourScheme() === 'light' ? light : dark;
|
||||
|
||||
const logout = props.presence.logoutAt ? new Date(props.presence.logoutAt * 1000) : null;
|
||||
const since_logout = useTimeSince(logout ?? new Date(0));
|
||||
const game = 'name' in props.presence.game ? props.presence.game : null;
|
||||
|
||||
if (props.presence.state === PresenceState.ONLINE || props.presence.state === PresenceState.PLAYING) {
|
||||
|
|
@ -128,7 +131,7 @@ function FriendPresence(props: {
|
|||
|
||||
return <View>
|
||||
<Text style={[styles.presenceText, styles.presenceTextOffline, theme.text]}>Offline</Text>
|
||||
{logout ? <Text style={[styles.presenceText, styles.presenceTextOffline, theme.text]}>Last seen {logout.toLocaleString('en-GB')}</Text> : null}
|
||||
{logout ? <Text style={[styles.presenceText, styles.presenceTextOffline, theme.text]}>Last seen {since_logout}</Text> : null}
|
||||
</View>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { Image, ImageStyle, Platform, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import ipc from '../ipc.js';
|
||||
import { useAccentColour, useColourScheme, User } from '../util.js';
|
||||
import { useAccentColour, useColourScheme, User, useTimeSince } from '../util.js';
|
||||
import { Friend, Presence, PresenceState } from '../../../api/coral-types.js';
|
||||
import { TEXT_COLOUR_ACTIVE, TEXT_COLOUR_DARK, TEXT_COLOUR_LIGHT } from '../constants.js';
|
||||
import Section, { HEADER_SIZE } from './section.js';
|
||||
|
|
@ -95,11 +95,14 @@ function FriendPresence(props: {
|
|||
}) {
|
||||
const theme = useColourScheme() === 'light' ? light : dark;
|
||||
|
||||
const logout = props.presence.logoutAt ? new Date(props.presence.logoutAt * 1000) : null;
|
||||
const since_logout = useTimeSince(logout ?? new Date(0), true);
|
||||
|
||||
if (props.presence.state === PresenceState.ONLINE || props.presence.state === PresenceState.PLAYING) {
|
||||
return <Text style={[styles.presenceText, theme.text, styles.presenceTextOnline]}>Playing</Text>;
|
||||
}
|
||||
|
||||
return <Text style={[styles.presenceText, styles.presenceTextOffline, theme.text]}>Offline</Text>;
|
||||
return <Text style={[styles.presenceText, styles.presenceTextOffline, theme.text]}>{logout ? since_logout : 'Offline'}</Text>;
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
|
|
|||
|
|
@ -249,3 +249,54 @@ export function useActiveDiscordUser() {
|
|||
|
||||
return user;
|
||||
}
|
||||
|
||||
export function useTimeSince(time: Date, short = false) {
|
||||
const [now, setNow] = useState(Date.now());
|
||||
|
||||
const [since, update_in] = getTimeSince(time, now, short ? short_time_since_intervals : time_since_intervals);
|
||||
const update_at = Date.now() + update_in;
|
||||
|
||||
useEffect(() => {
|
||||
const timeout = setTimeout(() => setNow(Date.now()), Math.max(1000, update_at - Date.now()));
|
||||
return () => clearTimeout(timeout);
|
||||
}, [time, short, update_at]);
|
||||
|
||||
return since;
|
||||
}
|
||||
|
||||
interface TimeSinceInterval {
|
||||
interval: number;
|
||||
max: number;
|
||||
string: (count: number) => string;
|
||||
}
|
||||
|
||||
const time_since_intervals: TimeSinceInterval[] = [
|
||||
{interval: 1000, max: 10, string: () => 'just now'},
|
||||
{interval: 1000, max: 60, string: c => c + ' second' + (c === 1 ? '' : 's') + ' ago'},
|
||||
{interval: 60 * 1000, max: 60, string: c => c + ' minute' + (c === 1 ? '' : 's') + ' ago'},
|
||||
{interval: 60 * 60 * 1000, max: 24, string: c => c + ' hour' + (c === 1 ? '' : 's') + ' ago'},
|
||||
{interval: 24 * 60 * 60 * 1000, max: Infinity, string: c => c + ' day' + (c === 1 ? '' : 's') + ' ago'},
|
||||
];
|
||||
const short_time_since_intervals: TimeSinceInterval[] = [
|
||||
{interval: 1000, max: 10, string: () => 'Just now'},
|
||||
{interval: 1000, max: 60, string: c => c + ' sec' + (c === 1 ? '' : 's')},
|
||||
{interval: 60 * 1000, max: 60, string: c => c + ' min' + (c === 1 ? '' : 's')},
|
||||
{interval: 60 * 60 * 1000, max: 24, string: c => c + ' hr' + (c === 1 ? '' : 's')},
|
||||
{interval: 24 * 60 * 60 * 1000, max: Infinity, string: c => c + ' day' + (c === 1 ? '' : 's')},
|
||||
];
|
||||
|
||||
function getTimeSince(time: Date | number, now = Date.now(), intervals = time_since_intervals): [string, number] {
|
||||
if (time instanceof Date) time = time.getTime();
|
||||
|
||||
const elapsed = Math.max(0, now - time);
|
||||
const last = intervals[time_since_intervals.length - 1];
|
||||
|
||||
for (const i of intervals) {
|
||||
if (elapsed < i.max * i.interval || last === i) {
|
||||
const count = Math.floor(elapsed / i.interval);
|
||||
return [i.string.call(null, count), i.interval - (elapsed - (count * i.interval))];
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Invalid intervals');
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user