feat: Add presence heartbeat for Matrix online status

- matrix-gateway: POST /internal/matrix/presence/online endpoint
- usePresenceHeartbeat hook with activity tracking
- Auto away after 5 min inactivity
- Offline on page close/visibility change
- Integrated in MatrixChatRoom component
This commit is contained in:
Apple
2025-11-27 00:19:40 -08:00
parent 5bed515852
commit 3de3c8cb36
6371 changed files with 1317450 additions and 932 deletions

View File

@@ -0,0 +1,36 @@
/**
* Wallet Adapter (MVP Stub)
*
* On MVP: returns mock data or reads from DB/stub
* Future: integrate with on-chain data
*/
import type { Balance } from '../../domain/wallet/types';
/**
* Get balances from external source (on-chain / DB / stub)
*/
export async function getBalances(userId: string): Promise<Balance[]> {
// MVP: Return mock data
// TODO: Replace with actual DB/on-chain integration
return [
{ symbol: 'DAAR', amount: '0.0' },
{ symbol: 'DAARION', amount: '0.0' },
];
}
/**
* Get staked DAARION amount
*/
export async function getStakedDaarion(userId: string): Promise<number> {
// MVP: Return mock data
// TODO: Replace with actual DB/on-chain integration
return 0.0;
}
export const walletAdapter = {
getBalances,
getStakedDaarion,
};

View File

@@ -0,0 +1,23 @@
/**
* Wallet Service Interface
* Based on: core-services-mvp.md, updated for MicroDAO requirements
*/
import type { Balance } from '../../domain/wallet/types';
export interface WalletService {
getBalances(userId: string): Promise<Balance[]>;
getDaarionBalance(userId: string): Promise<number>;
// MicroDAO access checks (balance-based, no staking)
hasEnoughForMicroDaoCreate(userId: string): Promise<boolean>; // 1 DAARION
hasEnoughForAdminRole(userId: string): Promise<boolean>; // 1 DAARION
hasEnoughForMicroDaoUsage(userId: string): Promise<boolean>; // 0.01 DAARION
// Legacy methods (deprecated)
hasEnoughForDaoCreate(userId: string): Promise<boolean>;
hasEnoughForVendorRegister(userId: string): Promise<boolean>;
hasEnoughForPlatformCreate(userId: string): Promise<boolean>;
}

View File

@@ -0,0 +1,85 @@
/**
* Wallet Service (MVP)
* Based on: core-services-mvp.md
*
* Responsibilities:
* - Read DAAR / DAARION balances
* - Provide helper functions for access checks
*/
import type { WalletService as IWalletService } from './wallet.interface';
import { walletAdapter } from './wallet.adapter';
import type { Balance, TokenSymbol } from '../../domain/wallet/types';
export class WalletService implements IWalletService {
/**
* Get user balances for DAAR and DAARION
*/
async getBalances(userId: string): Promise<Balance[]> {
return walletAdapter.getBalances(userId);
}
/**
* Check if user has enough DAARION to create a MicroDAO
* Requires: 1 DAARION on balance (not staked)
*/
async hasEnoughForMicroDaoCreate(userId: string): Promise<boolean> {
const balances = await this.getBalances(userId);
const daarion = balances.find(b => b.symbol === 'DAARION');
return daarion ? parseFloat(daarion.amount) >= 1.0 : false;
}
/**
* Check if user has enough DAARION to be Admin
* Requires: 1 DAARION on balance (not staked)
*/
async hasEnoughForAdminRole(userId: string): Promise<boolean> {
return this.hasEnoughForMicroDaoCreate(userId);
}
/**
* Check if user has enough DAARION to use MicroDAO service
* Requires: 0.01 DAARION on balance (not staked)
*/
async hasEnoughForMicroDaoUsage(userId: string): Promise<boolean> {
const balances = await this.getBalances(userId);
const daarion = balances.find(b => b.symbol === 'DAARION');
return daarion ? parseFloat(daarion.amount) >= 0.01 : false;
}
/**
* Get DAARION balance for user
*/
async getDaarionBalance(userId: string): Promise<number> {
const balances = await this.getBalances(userId);
const daarion = balances.find(b => b.symbol === 'DAARION');
return daarion ? parseFloat(daarion.amount) : 0;
}
// Legacy methods (deprecated, kept for backward compatibility)
/**
* @deprecated Use hasEnoughForMicroDaoCreate instead
*/
async hasEnoughForDaoCreate(userId: string): Promise<boolean> {
return this.hasEnoughForMicroDaoCreate(userId);
}
/**
* @deprecated Not used in current implementation
*/
async hasEnoughForVendorRegister(userId: string): Promise<boolean> {
return this.hasEnoughForMicroDaoUsage(userId);
}
/**
* @deprecated Not used in current implementation
*/
async hasEnoughForPlatformCreate(userId: string): Promise<boolean> {
return this.hasEnoughForMicroDaoCreate(userId);
}
}
// Singleton instance
export const walletService = new WalletService();