mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 23:16:21 +00:00
Merge remote-tracking branch 'fork/main'
# Conflicts: # public/configuration/UITexts_en.json5.example # public/configuration/UITexts_it.json5.example # src/components/MainView.tsx # src/css/friends/FriendsView.css
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { MessengerFriend } from './MessengerFriend';
|
||||
import { MessengerThread } from './MessengerThread';
|
||||
import { MessengerThreadChat } from './MessengerThreadChat';
|
||||
|
||||
const makeThread = (participantId: number): MessengerThread =>
|
||||
{
|
||||
const friend = new MessengerFriend();
|
||||
friend.id = participantId;
|
||||
return new MessengerThread(friend);
|
||||
};
|
||||
|
||||
describe('MessengerThread.setMessagesReadFromUser', () =>
|
||||
{
|
||||
it('marks only the given user\'s messages as READ', () =>
|
||||
{
|
||||
const thread = makeThread(7);
|
||||
const mine = thread.addMessage(100, 'a', 0, null, MessengerThreadChat.CHAT);
|
||||
const theirs = thread.addMessage(7, 'b', 0, null, MessengerThreadChat.CHAT);
|
||||
|
||||
thread.setMessagesReadFromUser(100);
|
||||
|
||||
expect(mine.status).toBe(MessengerThreadChat.READ);
|
||||
expect(theirs.status).toBe(MessengerThreadChat.SENT);
|
||||
});
|
||||
});
|
||||
@@ -99,6 +99,16 @@ export class MessengerThread
|
||||
this._unreadCount = 0;
|
||||
}
|
||||
|
||||
public setMessagesReadFromUser(userId: number): void
|
||||
{
|
||||
for(const group of this._groups)
|
||||
{
|
||||
if(group.userId !== userId) continue;
|
||||
|
||||
for(const chat of group.chats) chat.setStatus(MessengerThreadChat.READ);
|
||||
}
|
||||
}
|
||||
|
||||
public get threadId(): number
|
||||
{
|
||||
return this._threadId;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { MessengerThreadChat } from './MessengerThreadChat';
|
||||
|
||||
describe('MessengerThreadChat.offlineDelivered', () =>
|
||||
{
|
||||
it('is true for a CHAT message with extraData "offline"', () =>
|
||||
{
|
||||
const chat = new MessengerThreadChat(5, 'hello', 60, 'offline', MessengerThreadChat.CHAT);
|
||||
expect(chat.offlineDelivered).toBe(true);
|
||||
});
|
||||
|
||||
it('is false for a normal CHAT message with no extraData', () =>
|
||||
{
|
||||
const chat = new MessengerThreadChat(5, 'hello', 0, null, MessengerThreadChat.CHAT);
|
||||
expect(chat.offlineDelivered).toBe(false);
|
||||
});
|
||||
|
||||
it('is false when extraData is some other value (e.g. group chat data)', () =>
|
||||
{
|
||||
const chat = new MessengerThreadChat(5, 'hi', 0, 'Bob/figurestr/5', MessengerThreadChat.CHAT);
|
||||
expect(chat.offlineDelivered).toBe(false);
|
||||
});
|
||||
|
||||
it('is false for a non-CHAT type even if extraData is "offline"', () =>
|
||||
{
|
||||
const chat = new MessengerThreadChat(5, 'hi', 0, 'offline', MessengerThreadChat.ROOM_INVITE);
|
||||
expect(chat.offlineDelivered).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('MessengerThreadChat status', () =>
|
||||
{
|
||||
it('defaults to SENT', () =>
|
||||
{
|
||||
const chat = new MessengerThreadChat(5, 'hi', 0, null, MessengerThreadChat.CHAT);
|
||||
expect(chat.status).toBe(MessengerThreadChat.SENT);
|
||||
});
|
||||
|
||||
it('can be set to READ', () =>
|
||||
{
|
||||
const chat = new MessengerThreadChat(5, 'hi', 0, null, MessengerThreadChat.CHAT);
|
||||
chat.setStatus(MessengerThreadChat.READ);
|
||||
expect(chat.status).toBe(MessengerThreadChat.READ);
|
||||
});
|
||||
});
|
||||
@@ -4,10 +4,13 @@ export class MessengerThreadChat
|
||||
public static ROOM_INVITE: number = 1;
|
||||
public static STATUS_NOTIFICATION: number = 2;
|
||||
public static SECURITY_NOTIFICATION: number = 3;
|
||||
public static SENT: number = 0;
|
||||
public static READ: number = 1;
|
||||
private static CHAT_ID: number = 0;
|
||||
|
||||
private _id: number;
|
||||
private _type: number;
|
||||
private _status: number = MessengerThreadChat.SENT;
|
||||
private _senderId: number;
|
||||
private _message: string;
|
||||
private _secondsSinceSent: number;
|
||||
@@ -74,6 +77,21 @@ export class MessengerThreadChat
|
||||
return this._extraData;
|
||||
}
|
||||
|
||||
public get offlineDelivered(): boolean
|
||||
{
|
||||
return (this._type === MessengerThreadChat.CHAT) && (this._extraData === 'offline');
|
||||
}
|
||||
|
||||
public get status(): number
|
||||
{
|
||||
return this._status;
|
||||
}
|
||||
|
||||
public setStatus(status: number): void
|
||||
{
|
||||
this._status = status;
|
||||
}
|
||||
|
||||
public get date(): Date
|
||||
{
|
||||
return this._date;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { MessengerFriend } from './MessengerFriend';
|
||||
import { countFriendsByCategory, filterFriendsByCategory } from './friendCategory.helpers';
|
||||
|
||||
const makeFriend = (id: number, categoryId: number): MessengerFriend =>
|
||||
{
|
||||
const friend = new MessengerFriend();
|
||||
friend.id = id;
|
||||
friend.categoryId = categoryId;
|
||||
return friend;
|
||||
};
|
||||
|
||||
describe('filterFriendsByCategory', () =>
|
||||
{
|
||||
const friends = [ makeFriend(1, 0), makeFriend(2, 5), makeFriend(3, 5), makeFriend(4, 8) ];
|
||||
|
||||
it('returns all friends when categoryId is 0 (All)', () =>
|
||||
{
|
||||
expect(filterFriendsByCategory(friends, 0)).toHaveLength(4);
|
||||
});
|
||||
|
||||
it('returns only the friends in the given category', () =>
|
||||
{
|
||||
expect(filterFriendsByCategory(friends, 5).map(f => f.id)).toEqual([ 2, 3 ]);
|
||||
});
|
||||
|
||||
it('returns an empty array for a category with no members', () =>
|
||||
{
|
||||
expect(filterFriendsByCategory(friends, 99)).toEqual([]);
|
||||
});
|
||||
|
||||
it('is null-safe', () =>
|
||||
{
|
||||
expect(filterFriendsByCategory(null, 5)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('countFriendsByCategory', () =>
|
||||
{
|
||||
const friends = [ makeFriend(1, 0), makeFriend(2, 5), makeFriend(3, 5) ];
|
||||
|
||||
it('counts members per category id', () =>
|
||||
{
|
||||
const counts = countFriendsByCategory(friends);
|
||||
expect(counts.get(0)).toBe(1);
|
||||
expect(counts.get(5)).toBe(2);
|
||||
});
|
||||
|
||||
it('is null-safe', () =>
|
||||
{
|
||||
expect(countFriendsByCategory(null).size).toBe(0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { MessengerFriend } from './MessengerFriend';
|
||||
|
||||
/**
|
||||
* Filter a friend list to a single category. categoryId 0 means
|
||||
* "All" (no filtering) and returns the list unchanged.
|
||||
*/
|
||||
export const filterFriendsByCategory = (friends: MessengerFriend[], categoryId: number): MessengerFriend[] =>
|
||||
{
|
||||
if(!friends) return [];
|
||||
|
||||
if(!categoryId) return friends;
|
||||
|
||||
return friends.filter(friend => (friend.categoryId === categoryId));
|
||||
};
|
||||
|
||||
/**
|
||||
* Count how many friends belong to each category id. Used to render
|
||||
* member counts on the group chips.
|
||||
*/
|
||||
export const countFriendsByCategory = (friends: MessengerFriend[]): Map<number, number> =>
|
||||
{
|
||||
const counts = new Map<number, number>();
|
||||
|
||||
if(!friends) return counts;
|
||||
|
||||
for(const friend of friends)
|
||||
{
|
||||
counts.set(friend.categoryId, (counts.get(friend.categoryId) ?? 0) + 1);
|
||||
}
|
||||
|
||||
return counts;
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './friendCategory.helpers';
|
||||
export * from './GetGroupChatData';
|
||||
export * from './IGroupChatData';
|
||||
export * from './MessengerFriend';
|
||||
|
||||
Reference in New Issue
Block a user