Fix bugs in dm tab
This commit is contained in:
parent
b7c322d473
commit
06bae231ef
5 changed files with 86 additions and 110 deletions
|
@ -56,9 +56,10 @@ function InviteList({ isOpen, onRequestClose }) {
|
||||||
function renderRoomTile(roomId) {
|
function renderRoomTile(roomId) {
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
const myRoom = mx.getRoom(roomId);
|
const myRoom = mx.getRoom(roomId);
|
||||||
|
if (!myRoom) return null;
|
||||||
const roomName = myRoom.name;
|
const roomName = myRoom.name;
|
||||||
let roomAlias = myRoom.getCanonicalAlias();
|
let roomAlias = myRoom.getCanonicalAlias();
|
||||||
if (roomAlias === null) roomAlias = myRoom.roomId;
|
if (!roomAlias) roomAlias = myRoom.roomId;
|
||||||
const inviterName = myRoom.getMember(mx.getUserId())?.events?.member?.getSender?.() ?? '';
|
const inviterName = myRoom.getMember(mx.getUserId())?.events?.member?.getSender?.() ?? '';
|
||||||
return (
|
return (
|
||||||
<RoomTile
|
<RoomTile
|
||||||
|
@ -97,12 +98,13 @@ function InviteList({ isOpen, onRequestClose }) {
|
||||||
{
|
{
|
||||||
Array.from(initMatrix.roomList.inviteDirects).map((roomId) => {
|
Array.from(initMatrix.roomList.inviteDirects).map((roomId) => {
|
||||||
const myRoom = initMatrix.matrixClient.getRoom(roomId);
|
const myRoom = initMatrix.matrixClient.getRoom(roomId);
|
||||||
|
if (myRoom === null) return null;
|
||||||
const roomName = myRoom.name;
|
const roomName = myRoom.name;
|
||||||
return (
|
return (
|
||||||
<RoomTile
|
<RoomTile
|
||||||
key={myRoom.roomId}
|
key={myRoom.roomId}
|
||||||
name={roomName}
|
name={roomName}
|
||||||
id={myRoom.getDMInviter()}
|
id={myRoom.getDMInviter() || roomId}
|
||||||
options={
|
options={
|
||||||
procInvite.has(myRoom.roomId)
|
procInvite.has(myRoom.roomId)
|
||||||
? (<Spinner size="small" />)
|
? (<Spinner size="small" />)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import initMatrix from '../../../client/initMatrix';
|
import initMatrix from '../../../client/initMatrix';
|
||||||
import cons from '../../../client/state/cons';
|
import cons from '../../../client/state/cons';
|
||||||
|
@ -9,12 +10,12 @@ import { roomIdByActivity } from '../../../util/sort';
|
||||||
import RoomsCategory from './RoomsCategory';
|
import RoomsCategory from './RoomsCategory';
|
||||||
|
|
||||||
const drawerPostie = new Postie();
|
const drawerPostie = new Postie();
|
||||||
function Directs() {
|
function Directs({ size }) {
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
const { roomList, notifications } = initMatrix;
|
const { roomList, notifications } = initMatrix;
|
||||||
const [directIds, setDirectIds] = useState([]);
|
const [directIds, setDirectIds] = useState([]);
|
||||||
|
|
||||||
useEffect(() => setDirectIds([...roomList.directs].sort(roomIdByActivity)), []);
|
useEffect(() => setDirectIds([...roomList.directs].sort(roomIdByActivity)), [size]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleTimeline = (event, room, toStartOfTimeline, removed, data) => {
|
const handleTimeline = (event, room, toStartOfTimeline, removed, data) => {
|
||||||
|
@ -63,5 +64,8 @@ function Directs() {
|
||||||
|
|
||||||
return <RoomsCategory name="People" hideHeader roomIds={directIds} drawerPostie={drawerPostie} />;
|
return <RoomsCategory name="People" hideHeader roomIds={directIds} drawerPostie={drawerPostie} />;
|
||||||
}
|
}
|
||||||
|
Directs.propTypes = {
|
||||||
|
size: PropTypes.number.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default Directs;
|
export default Directs;
|
||||||
|
|
|
@ -42,12 +42,15 @@ function Drawer() {
|
||||||
const [spaceId] = useSelectedSpace();
|
const [spaceId] = useSelectedSpace();
|
||||||
const [, forceUpdate] = useForceUpdate();
|
const [, forceUpdate] = useForceUpdate();
|
||||||
const scrollRef = useRef(null);
|
const scrollRef = useRef(null);
|
||||||
|
const { roomList } = initMatrix;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const { roomList } = initMatrix;
|
const handleUpdate = () => {
|
||||||
roomList.on(cons.events.roomList.ROOMLIST_UPDATED, forceUpdate);
|
forceUpdate();
|
||||||
|
};
|
||||||
|
roomList.on(cons.events.roomList.ROOMLIST_UPDATED, handleUpdate);
|
||||||
return () => {
|
return () => {
|
||||||
roomList.removeListener(cons.events.roomList.ROOMLIST_UPDATED, forceUpdate);
|
roomList.removeListener(cons.events.roomList.ROOMLIST_UPDATED, handleUpdate);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -68,7 +71,7 @@ function Drawer() {
|
||||||
{
|
{
|
||||||
selectedTab !== cons.tabs.DIRECTS
|
selectedTab !== cons.tabs.DIRECTS
|
||||||
? <Home spaceId={spaceId} />
|
? <Home spaceId={spaceId} />
|
||||||
: <Directs />
|
: <Directs size={roomList.directs.size} />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
|
@ -113,17 +113,20 @@ async function join(roomIdOrAlias, isDM, via) {
|
||||||
* @param {string} roomId
|
* @param {string} roomId
|
||||||
* @param {boolean} isDM
|
* @param {boolean} isDM
|
||||||
*/
|
*/
|
||||||
function leave(roomId) {
|
async function leave(roomId) {
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
const isDM = initMatrix.roomList.directs.has(roomId);
|
const isDM = initMatrix.roomList.directs.has(roomId);
|
||||||
mx.leave(roomId)
|
try {
|
||||||
.then(() => {
|
await mx.leave(roomId);
|
||||||
|
await mx.forget(roomId);
|
||||||
appDispatcher.dispatch({
|
appDispatcher.dispatch({
|
||||||
type: cons.actions.room.LEAVE,
|
type: cons.actions.room.LEAVE,
|
||||||
roomId,
|
roomId,
|
||||||
isDM,
|
isDM,
|
||||||
});
|
});
|
||||||
}).catch();
|
} catch {
|
||||||
|
console.error('Unable to leave room.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function create(options, isDM = false) {
|
async function create(options, isDM = false) {
|
||||||
|
|
|
@ -6,6 +6,21 @@ function isMEventSpaceChild(mEvent) {
|
||||||
return mEvent.getType() === 'm.space.child' && Object.keys(mEvent.getContent()).length > 0;
|
return mEvent.getType() === 'm.space.child' && Object.keys(mEvent.getContent()).length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {() => boolean} callback if return true wait will over else callback will be called again.
|
||||||
|
* @param {number} timeout timeout to callback
|
||||||
|
* @param {number} maxTry maximum callback try > 0. -1 means no limit
|
||||||
|
*/
|
||||||
|
async function waitFor(callback, timeout = 400, maxTry = -1) {
|
||||||
|
if (maxTry === 0) return false;
|
||||||
|
const isOver = async () => new Promise((resolve) => {
|
||||||
|
setTimeout(() => resolve(callback()), timeout);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (await isOver()) return true;
|
||||||
|
return waitFor(callback, timeout, maxTry - 1);
|
||||||
|
}
|
||||||
|
|
||||||
class RoomList extends EventEmitter {
|
class RoomList extends EventEmitter {
|
||||||
constructor(matrixClient) {
|
constructor(matrixClient) {
|
||||||
super();
|
super();
|
||||||
|
@ -228,6 +243,7 @@ class RoomList extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
_isDMInvite(room) {
|
_isDMInvite(room) {
|
||||||
|
if (this.mDirects.has(room.roomId)) return true;
|
||||||
const me = room.getMember(this.matrixClient.getUserId());
|
const me = room.getMember(this.matrixClient.getUserId());
|
||||||
const myEventContent = me.events.member.getContent();
|
const myEventContent = me.events.member.getContent();
|
||||||
return myEventContent.membership === 'invite' && myEventContent.is_direct;
|
return myEventContent.membership === 'invite' && myEventContent.is_direct;
|
||||||
|
@ -243,22 +259,11 @@ class RoomList extends EventEmitter {
|
||||||
latestMDirects.forEach((directId) => {
|
latestMDirects.forEach((directId) => {
|
||||||
const myRoom = this.matrixClient.getRoom(directId);
|
const myRoom = this.matrixClient.getRoom(directId);
|
||||||
if (this.mDirects.has(directId)) return;
|
if (this.mDirects.has(directId)) return;
|
||||||
|
|
||||||
// Update mDirects
|
|
||||||
this.mDirects.add(directId);
|
this.mDirects.add(directId);
|
||||||
|
|
||||||
if (myRoom === null) return;
|
if (myRoom === null) return;
|
||||||
|
if (myRoom.getMyMembership() === 'join') {
|
||||||
if (this._isDMInvite(myRoom)) return;
|
|
||||||
|
|
||||||
if (myRoom.getMyMembership === 'join' && !this.directs.has(directId)) {
|
|
||||||
this.directs.add(directId);
|
this.directs.add(directId);
|
||||||
}
|
|
||||||
|
|
||||||
// Newly added room.
|
|
||||||
// at this time my membership can be invite | join
|
|
||||||
if (myRoom.getMyMembership() === 'join' && this.rooms.has(directId)) {
|
|
||||||
// found a DM which accidentally gets added to this.rooms
|
|
||||||
this.rooms.delete(directId);
|
this.rooms.delete(directId);
|
||||||
this.emit(cons.events.roomList.ROOMLIST_UPDATED);
|
this.emit(cons.events.roomList.ROOMLIST_UPDATED);
|
||||||
}
|
}
|
||||||
|
@ -298,23 +303,17 @@ class RoomList extends EventEmitter {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.matrixClient.on('Room.myMembership', (room, membership, prevMembership) => {
|
this.matrixClient.on('Room.myMembership', async (room, membership, prevMembership) => {
|
||||||
// room => prevMembership = null | invite | join | leave | kick | ban | unban
|
// room => prevMembership = null | invite | join | leave | kick | ban | unban
|
||||||
// room => membership = invite | join | leave | kick | ban | unban
|
// room => membership = invite | join | leave | kick | ban | unban
|
||||||
const { roomId } = room;
|
const { roomId } = room;
|
||||||
|
const isRoomReady = () => this.matrixClient.getRoom(roomId) !== null;
|
||||||
|
if (['join', 'invite'].includes(membership) && isRoomReady() === false) {
|
||||||
|
if (await waitFor(isRoomReady, 200, 100) === false) return;
|
||||||
|
}
|
||||||
|
|
||||||
if (membership === 'unban') return;
|
if (membership === 'unban') return;
|
||||||
|
|
||||||
// When user_reject/sender_undo room invite
|
|
||||||
if (prevMembership === 'invite') {
|
|
||||||
if (this.inviteDirects.has(roomId)) this.inviteDirects.delete(roomId);
|
|
||||||
else if (this.inviteSpaces.has(roomId)) this.inviteSpaces.delete(roomId);
|
|
||||||
else this.inviteRooms.delete(roomId);
|
|
||||||
|
|
||||||
this.emit(cons.events.roomList.INVITELIST_UPDATED, roomId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// When user get invited
|
|
||||||
if (membership === 'invite') {
|
if (membership === 'invite') {
|
||||||
if (this._isDMInvite(room)) this.inviteDirects.add(roomId);
|
if (this._isDMInvite(room)) this.inviteDirects.add(roomId);
|
||||||
else if (room.isSpaceRoom()) this.inviteSpaces.add(roomId);
|
else if (room.isSpaceRoom()) this.inviteSpaces.add(roomId);
|
||||||
|
@ -324,13 +323,26 @@ class RoomList extends EventEmitter {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When user join room (first time) or start DM.
|
if (prevMembership === 'invite') {
|
||||||
if ((prevMembership === null || prevMembership === 'invite') && membership === 'join') {
|
if (this.inviteDirects.has(roomId)) this.inviteDirects.delete(roomId);
|
||||||
|
else if (this.inviteSpaces.has(roomId)) this.inviteSpaces.delete(roomId);
|
||||||
|
else this.inviteRooms.delete(roomId);
|
||||||
|
|
||||||
|
this.emit(cons.events.roomList.INVITELIST_UPDATED, roomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['leave', 'kick', 'ban'].includes(membership)) {
|
||||||
|
if (this.directs.has(roomId)) this.directs.delete(roomId);
|
||||||
|
else if (this.spaces.has(roomId)) this.deleteFromSpaces(roomId);
|
||||||
|
else this.rooms.delete(roomId);
|
||||||
|
this.emit(cons.events.roomList.ROOM_LEAVED, roomId);
|
||||||
|
this.emit(cons.events.roomList.ROOMLIST_UPDATED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// when user create room/DM OR accept room/dm invite from this client.
|
// when user create room/DM OR accept room/dm invite from this client.
|
||||||
// we will update this.rooms/this.directs with user action
|
// we will update this.rooms/this.directs with user action
|
||||||
if (this.directs.has(roomId) || this.spaces.has(roomId) || this.rooms.has(roomId)) return;
|
if (membership === 'join' && this.processingRooms.has(roomId)) {
|
||||||
|
|
||||||
if (this.processingRooms.has(roomId)) {
|
|
||||||
const procRoomInfo = this.processingRooms.get(roomId);
|
const procRoomInfo = this.processingRooms.get(roomId);
|
||||||
|
|
||||||
if (procRoomInfo.isDM) this.directs.add(roomId);
|
if (procRoomInfo.isDM) this.directs.add(roomId);
|
||||||
|
@ -344,68 +356,20 @@ class RoomList extends EventEmitter {
|
||||||
this.processingRooms.delete(roomId);
|
this.processingRooms.delete(roomId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (room.isSpaceRoom()) {
|
|
||||||
this.addToSpaces(roomId);
|
|
||||||
|
|
||||||
this.emit(cons.events.roomList.ROOM_JOINED, roomId);
|
if (this.mDirects.has(roomId) && membership === 'join') {
|
||||||
this.emit(cons.events.roomList.ROOMLIST_UPDATED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// below code intented to work when user create room/DM
|
|
||||||
// OR accept room/dm invite from other client.
|
|
||||||
// and we have to update our client. (it's ok to have 10sec delay)
|
|
||||||
|
|
||||||
// create a buffer of 10sec and HOPE client.accoundData get updated
|
|
||||||
// then accoundData event listener will update this.mDirects.
|
|
||||||
// and we will be able to know if it's a DM.
|
|
||||||
// ----------
|
|
||||||
// less likely situation:
|
|
||||||
// if we don't get accountData with 10sec then:
|
|
||||||
// we will temporary add it to this.rooms.
|
|
||||||
// and in future when accountData get updated
|
|
||||||
// accountData listener will automatically goona REMOVE it from this.rooms
|
|
||||||
// and will ADD it to this.directs
|
|
||||||
// and emit the cons.events.roomList.ROOMLIST_UPDATED to update the UI.
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
if (this.directs.has(roomId) || this.spaces.has(roomId) || this.rooms.has(roomId)) return;
|
|
||||||
if (this.mDirects.has(roomId)) this.directs.add(roomId);
|
|
||||||
else this.rooms.add(roomId);
|
|
||||||
|
|
||||||
this.emit(cons.events.roomList.ROOM_JOINED, roomId);
|
|
||||||
this.emit(cons.events.roomList.ROOMLIST_UPDATED);
|
|
||||||
}, 10000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// when room is a DM add/remove it from DM's and return.
|
|
||||||
if (this.directs.has(roomId)) {
|
|
||||||
if (membership === 'leave' || membership === 'kick' || membership === 'ban') {
|
|
||||||
this.directs.delete(roomId);
|
|
||||||
this.emit(cons.events.roomList.ROOM_LEAVED, roomId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.mDirects.has(roomId)) {
|
|
||||||
if (membership === 'join') {
|
|
||||||
this.directs.add(roomId);
|
this.directs.add(roomId);
|
||||||
this.emit(cons.events.roomList.ROOM_JOINED, roomId);
|
this.emit(cons.events.roomList.ROOM_JOINED, roomId);
|
||||||
}
|
|
||||||
this.emit(cons.events.roomList.ROOMLIST_UPDATED);
|
this.emit(cons.events.roomList.ROOMLIST_UPDATED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// when room is not a DM add/remove it from rooms.
|
|
||||||
if (membership === 'leave' || membership === 'kick' || membership === 'ban') {
|
|
||||||
if (room.isSpaceRoom()) this.deleteFromSpaces(roomId);
|
|
||||||
else this.rooms.delete(roomId);
|
|
||||||
this.emit(cons.events.roomList.ROOM_LEAVED, roomId);
|
|
||||||
}
|
|
||||||
if (membership === 'join') {
|
if (membership === 'join') {
|
||||||
if (room.isSpaceRoom()) this.addToSpaces(roomId);
|
if (room.isSpaceRoom()) this.addToSpaces(roomId);
|
||||||
else this.rooms.add(roomId);
|
else this.rooms.add(roomId);
|
||||||
this.emit(cons.events.roomList.ROOM_JOINED, roomId);
|
this.emit(cons.events.roomList.ROOM_JOINED, roomId);
|
||||||
}
|
|
||||||
this.emit(cons.events.roomList.ROOMLIST_UPDATED);
|
this.emit(cons.events.roomList.ROOMLIST_UPDATED);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue