This commit is contained in:
MyNameIsBatman 2021-09-18 04:09:49 -03:00
parent f5d47756ce
commit a54be45a4f
10 changed files with 110 additions and 27 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

View File

@ -693,6 +693,18 @@
height: 16px;
}
&.icon-friendlist-warning {
background: url('../images/friendlist/icons/icon_warning.png');
width: 23px;
height: 21px;
}
&.icon-friendlist-new-message {
background: url('../images/friendlist/icons/icon_new_message.png');
width: 14px;
height: 16px;
}
&.spin {
animation: rotating 1s linear infinite;
}

View File

@ -77,7 +77,8 @@ export const FriendsMessageHandler: FC<{}> = props =>
dispatchFriendsState({
type: FriendsActions.ADD_CHAT_MESSAGE,
payload: {
chatMessage: new MessengerChatMessage(MessengerChatMessage.MESSAGE, userId, parser.messageText, parser.secondsSinceSent, parser.extraData)
chatMessage: new MessengerChatMessage(MessengerChatMessage.MESSAGE, userId, parser.messageText, parser.secondsSinceSent, parser.extraData),
boolValue: true
}
});
}, [ dispatchFriendsState ]);

View File

@ -6,19 +6,25 @@ export class MessengerChat
private _isRead: boolean;
private _messageGroups: MessengerChatMessageGroup[];
constructor(friendId: number, isRead: boolean = true)
constructor(friendId: number)
{
this._friendId = friendId;
this._isRead = isRead;
this._isRead = true;
this._messageGroups = [];
}
public addMessage(message: MessengerChatMessage): void
public addMessage(message: MessengerChatMessage, setAsNotRead: boolean = true, isSystem: boolean = false): void
{
if(!this.lastMessageGroup || this.lastMessageGroup.userId !== message.senderId) this._messageGroups.push(new MessengerChatMessageGroup(message.senderId));
if(!this.lastMessageGroup || this.lastMessageGroup.userId !== message.senderId || isSystem || this.lastMessageGroup.isSystem) this._messageGroups.push(new MessengerChatMessageGroup(message.senderId, isSystem));
this.lastMessageGroup.addMessage(message);
this._isRead = false;
if(setAsNotRead) this._isRead = false;
}
public read(): void
{
this._isRead = true;
}
public get friendId(): number

View File

@ -2,7 +2,8 @@ export class MessengerChatMessage
{
public static MESSAGE: number = 0;
public static ROOM_INVITE: number = 1;
public static SYSTEM_NOTIFICATION: number = 2;
public static SECURITY_ALERT: number = 2;
public static STATUS_ALERT: number = 3;
private _type: number;
private _senderId: number;

View File

@ -4,11 +4,13 @@ export class MessengerChatMessageGroup
{
private _userId: number;
private _messages: MessengerChatMessage[];
private _isSystem: boolean;
constructor(userId: number)
constructor(userId: number, isSystem: boolean)
{
this._userId = userId;
this._messages = [];
this._isSystem = isSystem;
}
public addMessage(message: MessengerChatMessage): void
@ -25,4 +27,9 @@ export class MessengerChatMessageGroup
{
return this._messages;
}
public get isSystem(): boolean
{
return this._isSystem;
}
}

View File

@ -19,6 +19,7 @@ export interface IFriendsState
friends: MessengerFriend[];
requests: MessengerRequest[];
activeChats: MessengerChat[];
firstChatEverOpen: boolean;
}
export interface IFriendsAction
@ -32,6 +33,7 @@ export interface IFriendsAction
chats?: MessengerChat[];
chatMessage?: MessengerChatMessage;
numberValue?: number;
boolValue?: boolean;
}
}
@ -43,6 +45,7 @@ export class FriendsActions
public static PROCESS_UPDATE: string = 'FA_PROCESS_UPDATE';
public static PROCESS_REQUESTS: string = 'FA_PROCESS_REQUESTS';
public static SET_ACTIVE_CHATS: string = 'FA_SET_ACTIVE_CHATS';
public static SET_CHAT_READ: string = 'FA_SET_CHAT_READ';
public static ADD_CHAT_MESSAGE: string = 'FA_ADD_CHAT_MESSAGE';
}
@ -50,7 +53,8 @@ export const initialFriends: IFriendsState = {
settings: null,
friends: [],
requests: [],
activeChats: []
activeChats: [],
firstChatEverOpen: false
}
export const FriendsReducer: Reducer<IFriendsState, IFriendsAction> = (state, action) =>
@ -145,11 +149,25 @@ export const FriendsReducer: Reducer<IFriendsState, IFriendsAction> = (state, ac
case FriendsActions.SET_ACTIVE_CHATS: {
const activeChats = (action.payload.chats || []);
if(!state.firstChatEverOpen && activeChats.length > 0) activeChats[0].addMessage(new MessengerChatMessage(MessengerChatMessage.SECURITY_ALERT, 0, null, 0), false, true);
return { ...state, activeChats, firstChatEverOpen: true };
}
case FriendsActions.SET_CHAT_READ: {
const friendId = action.payload.numberValue;
const activeChats = Array.from(state.activeChats);
let activeChatIndex = activeChats.findIndex(c => c.friendId === friendId);
if(activeChatIndex > -1) activeChats[activeChatIndex].read();
return { ...state, activeChats };
}
case FriendsActions.ADD_CHAT_MESSAGE: {
const message = action.payload.chatMessage;
const toFriendId = action.payload.numberValue;
const setAsNotRead = action.payload.boolValue;
const activeChats = Array.from(state.activeChats);
@ -157,11 +175,11 @@ export const FriendsReducer: Reducer<IFriendsState, IFriendsAction> = (state, ac
if(activeChatIndex === -1)
{
activeChats.push(new MessengerChat(message.senderId, false));
activeChats.push(new MessengerChat(message.senderId));
activeChatIndex = activeChats.length - 1;
}
activeChats[activeChatIndex].addMessage(message);
activeChats[activeChatIndex].addMessage(message, setAsNotRead);
return { ...state, activeChats };
}

View File

@ -1,5 +1,5 @@
.nitro-friends-messenger {
width: 300px;
width: 280px;
.friend-head {
position: relative;
@ -7,6 +7,13 @@
height: 40px;
overflow: hidden;
.icon {
position: absolute;
top: 1px;
right: 1px;
z-index: 10;
}
.avatar-image {
position: absolute;
margin-left: -27px;

View File

@ -50,7 +50,7 @@ export const FriendsMessengerView: FC<{}> = props =>
if(existingChatIndex === -1)
{
const clonedActiveChats = Array.from(activeChats);
clonedActiveChats.push(new MessengerChat(friendId, true));
clonedActiveChats.push(new MessengerChat(friendId));
dispatchFriendsState({
type: FriendsActions.SET_ACTIVE_CHATS,
@ -75,8 +75,24 @@ export const FriendsMessengerView: FC<{}> = props =>
return friend.figure;
}, [ friends ]);
const selectedChat = useMemo(() =>
const selectChat = useCallback((index: number) =>
{
const chat = activeChats[index];
if(!chat) return;
dispatchFriendsState({
type: FriendsActions.SET_CHAT_READ,
payload: {
numberValue: chat.friendId
}
});
setSelectedChatIndex(index);
}, [ activeChats, dispatchFriendsState ]);
const selectedChat = useMemo(() =>
{
return activeChats[selectedChatIndex];
}, [ activeChats, selectedChatIndex ]);
@ -131,7 +147,8 @@ export const FriendsMessengerView: FC<{}> = props =>
type: FriendsActions.ADD_CHAT_MESSAGE,
payload: {
chatMessage: new MessengerChatMessage(MessengerChatMessage.MESSAGE, 0, message, (new Date().getMilliseconds())),
numberValue: selectedChat.friendId
numberValue: selectedChat.friendId,
boolValue: false
}
});
setMessage('');
@ -152,7 +169,8 @@ export const FriendsMessengerView: FC<{}> = props =>
<div className="d-flex gap-2 overflow-auto pb-1">
{ activeChats && activeChats.map((chat, index) =>
{
return <div key={ index } className="friend-head bg-muted rounded flex-shrink-0 cursor-pointer" onClick={ () => setSelectedChatIndex(index) }>
return <div key={ index } className="friend-head rounded flex-shrink-0 cursor-pointer bg-muted" onClick={ () => selectChat(index) }>
{ !chat.isRead && <i className="icon icon-friendlist-new-message" /> }
<AvatarImageView figure={ getFriendFigure(chat.friendId) } headOnly={true} direction={3} />
</div>;
}) }
@ -176,18 +194,31 @@ export const FriendsMessengerView: FC<{}> = props =>
{ selectedChat.messageGroups.map((group, groupIndex) =>
{
return <div key={ groupIndex } className={ 'd-flex gap-2 w-100 justify-content-' + (group.userId === 0 ? 'end' : 'start') }>
{ group.userId !== 0 && <div className="message-avatar flex-shrink-0">
<AvatarImageView figure={ selectedChatFriend.figure } direction={ 2 } />
</div> }
<div className={ 'bg-light text-black border-radius mb-2 rounded py-1 px-2 messages-group-' + (group.userId === 0 ? 'right' : 'left') }>
{ group.isSystem && <>
{ group.messages.map((message, messageIndex) =>
{
return <div key={ messageIndex } className="text-break">{ message.message }</div>
}) }
</div>
{ group.userId === 0 && <div className="message-avatar flex-shrink-0">
<AvatarImageView figure={ GetSessionDataManager().figure } direction={ 4 } />
</div> }
{
return <div key={ messageIndex } className="text-break">
{ message.type === MessengerChatMessage.SECURITY_ALERT && <div className="bg-light rounded mb-2 d-flex gap-2 px-2 py-1 small text-muted align-items-center">
<i className="icon icon-friendlist-warning flex-shrink-0" />
<div>{ LocalizeText('messenger.moderationinfo') }</div>
</div> }
</div>
}) }
</> }
{ !group.isSystem && <>
{ group.userId !== 0 && <div className="message-avatar flex-shrink-0">
<AvatarImageView figure={ selectedChatFriend.figure } direction={ 2 } />
</div> }
<div className={ 'bg-light text-black border-radius mb-2 rounded py-1 px-2 messages-group-' + (group.userId === 0 ? 'right' : 'left') }>
{ group.messages.map((message, messageIndex) =>
{
return <div key={ messageIndex } className="text-break">{ message.message }</div>
}) }
</div>
{ group.userId === 0 && <div className="message-avatar flex-shrink-0">
<AvatarImageView figure={ GetSessionDataManager().figure } direction={ 4 } />
</div> }
</> }
</div>;
}) }
</div>