Use last_online_time from user_activity instead of profiles

This commit is contained in:
MartinBraquet
2025-10-14 17:53:29 +02:00
parent 7d87af8f5c
commit 4ad89acdc7
6 changed files with 53 additions and 27 deletions

View File

@@ -50,6 +50,7 @@ import {leavePrivateUserMessageChannel} from './leave-private-user-message-chann
import {updatePrivateUserMessageChannel} from './update-private-user-message-channel'
import {getNotifications} from './get-notifications'
import {updateNotifSettings} from './update-notif-setting'
import {setLastOnline} from './set-last-online'
import swaggerUi from "swagger-ui-express"
import * as fs from "fs"
import {sendSearchNotifications} from "api/send-search-notifications";
@@ -167,6 +168,7 @@ const handlers: { [k in APIPath]: APIHandler<k> } = {
'get-channel-seen-time': getLastSeenChannelTime,
'set-channel-seen-time': setChannelLastSeenTime,
'get-messages-count': getMessagesCount,
'set-last-online': setLastOnline,
}
Object.entries(handlers).forEach(([path, handler]) => {

View File

@@ -1,7 +1,7 @@
import {type APIHandler} from 'api/helpers/endpoint'
import {convertRow} from 'shared/love/supabase'
import {createSupabaseDirectClient} from 'shared/supabase/init'
import {from, join, limit, orderBy, renderSql, select, where,} from 'shared/supabase/sql-builder'
import {from, join, leftJoin, limit, orderBy, renderSql, select, where,} from 'shared/supabase/sql-builder'
import {getCompatibleProfiles} from 'api/compatible-profiles'
import {intersection} from 'lodash'
import {MAX_INT, MIN_BIO_LENGTH, MIN_INT} from "common/constants";
@@ -98,9 +98,10 @@ export const loadProfiles = async (props: profileQueryType) => {
}
const query = renderSql(
select('profiles.*, name, username, users.data as user'),
select('profiles.*, name, username, users.data as user, user_activity.last_online_time'),
from('profiles'),
join('users on users.id = profiles.user_id'),
leftJoin('user_activity on user_activity.user_id = profiles.user_id'),
where('looking_for_matches = true'),
// where(`pinned_url is not null and pinned_url != ''`),
where(

View File

@@ -0,0 +1,22 @@
import {APIHandler} from './helpers/endpoint'
import {createSupabaseDirectClient} from 'shared/supabase/init'
export const setLastOnline: APIHandler<'set-last-online'> = async (
_,
auth
) => {
if (!auth || !auth.uid) return
const pg = createSupabaseDirectClient()
const result = await pg.none(`
INSERT INTO user_activity (user_id, last_online_time)
VALUES ($1, now())
ON CONFLICT (user_id)
DO UPDATE
SET last_online_time = EXCLUDED.last_online_time
WHERE user_activity.last_online_time < now() - interval '1 minute';
`,
[auth.uid]
)
console.log('setLastOnline', result)
}

View File

@@ -28,7 +28,6 @@ CREATE TABLE IF NOT EXISTS profiles (
id BIGINT GENERATED ALWAYS AS IDENTITY NOT NULL,
is_smoker BOOLEAN,
is_vegetarian_or_vegan BOOLEAN,
last_online_time TIMESTAMPTZ DEFAULT now() NOT NULL,
last_modification_time TIMESTAMPTZ DEFAULT now() NOT NULL,
looking_for_matches BOOLEAN DEFAULT TRUE NOT NULL,
messaging_status TEXT DEFAULT 'open'::TEXT NOT NULL,
@@ -89,17 +88,11 @@ CREATE
OR REPLACE FUNCTION update_last_modification_time()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.last_online_time IS DISTINCT FROM OLD.last_online_time AND row(NEW.*) = row(OLD.*) THEN
-- Only last_online_time changed, do nothing
RETURN NEW;
END IF;
-- Some other column changed
NEW.last_modification_time = now();
RETURN NEW;
NEW.last_modification_time = now();
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_update_last_mod_time
BEFORE UPDATE
@@ -141,5 +134,3 @@ $$ LANGUAGE plpgsql;
CREATE TRIGGER trg_update_bio_text
BEFORE INSERT OR UPDATE OF bio ON profiles
FOR EACH ROW EXECUTE FUNCTION update_bio_text();

View File

@@ -405,6 +405,11 @@ export const API = (_apiTypeCheck = {
channelId: z.coerce.number(),
}),
},
'set-last-online': {
method: 'POST',
authed: true,
props: z.object({}),
},
'get-notifications': {
method: 'GET',
authed: true,

View File

@@ -1,18 +1,23 @@
import { useEffect } from 'react'
import { useProfile } from 'web/hooks/use-profile'
import { useIsAuthorized } from 'web/hooks/use-user'
import { run } from 'common/supabase/utils'
import { db } from 'web/lib/supabase/db'
import {useEffect} from 'react'
import {useProfile} from 'web/hooks/use-profile'
import {useIsAuthorized} from 'web/hooks/use-user'
import {api} from 'web/lib/api'
export const useOnline = () => {
const profile = useProfile()
const isAuthed = useIsAuthorized()
useEffect(() => {
if (!profile || !isAuthed) return
run(
db
.from('profiles')
.update({ last_online_time: new Date().toISOString() })
.eq('id', profile.id)
)
}, [])
void (async () => {
const date = new Date().toISOString()
// const result = await run(
// db
// .from('profiles')
// .update({ last_online_time: date })
// .eq('id', profile.id)
// )
api('set-last-online')
console.log('set last online time for', profile.id, date)
})()
}, [profile?.id, isAuthed])
}