Skip to content

Commit f9145a9

Browse files
committed
Fix host tests
1 parent d137242 commit f9145a9

File tree

6 files changed

+47
-125
lines changed

6 files changed

+47
-125
lines changed

packages/host/app/components/ai-assistant/attachment-picker/index.gts

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { restartableTask } from 'ember-concurrency';
88
import { TrackedSet } from 'tracked-built-ins';
99

1010
import { AddButton, Tooltip, Pill } from '@cardstack/boxel-ui/components';
11-
import { and, cn, eq, gt, not } from '@cardstack/boxel-ui/helpers';
11+
import { and, cn, eq, gt, not, or } from '@cardstack/boxel-ui/helpers';
1212

1313
import {
1414
chooseCard,
@@ -39,6 +39,7 @@ interface Signature {
3939
submode: Submode;
4040
maxNumberOfItemsToAttach?: number;
4141
autoAttachedCardTooltipMessage?: string;
42+
disabled?: boolean;
4243
};
4344
}
4445

@@ -119,7 +120,7 @@ export default class AiAssistantAttachmentPicker extends Component<Signature> {
119120
@iconWidth='14'
120121
@iconHeight='14'
121122
{{on 'click' this.chooseFile}}
122-
@disabled={{this.doChooseFile.isRunning}}
123+
@disabled={{(or this.doChooseFile.isRunning @disabled)}}
123124
data-test-choose-file-btn
124125
>
125126
<span class={{if this.files.length 'boxel-sr-only'}}>
@@ -133,7 +134,7 @@ export default class AiAssistantAttachmentPicker extends Component<Signature> {
133134
@iconWidth='14'
134135
@iconHeight='14'
135136
{{on 'click' this.chooseCard}}
136-
@disabled={{this.doChooseCard.isRunning}}
137+
@disabled={{(or this.doChooseCard.isRunning @disabled)}}
137138
data-test-choose-card-btn
138139
>
139140
<span class={{if this.cards.length 'boxel-sr-only'}}>

packages/host/app/components/ai-assistant/panel.gts

+1-2
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,7 @@ export default class AiAssistantPanel extends Component<Signature> {
657657
return Boolean(
658658
this.matrixService.currentRoomId &&
659659
this.maybeMonacoSDK &&
660-
this.doCreateRoom.isIdle &&
661-
!this.matrixService.isLoadingTimeline,
660+
this.doCreateRoom.isIdle,
662661
);
663662
}
664663
}

packages/host/app/components/matrix/room.gts

+23-5
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ import { TrackedObject, TrackedSet } from 'tracked-built-ins';
2727

2828
import { v4 as uuidv4 } from 'uuid';
2929

30-
import { BoxelButton } from '@cardstack/boxel-ui/components';
31-
import { eq, not } from '@cardstack/boxel-ui/helpers';
30+
import { BoxelButton, LoadingIndicator } from '@cardstack/boxel-ui/components';
31+
import { eq, not, or } from '@cardstack/boxel-ui/helpers';
3232

3333
import { ResolvedCodeRef, internalKeyFor } from '@cardstack/runtime-common';
3434
import { DEFAULT_LLM_LIST } from '@cardstack/runtime-common/matrix-constants';
@@ -104,7 +104,14 @@ export default class Room extends Component<Signature> {
104104
data-test-message-idx={{i}}
105105
/>
106106
{{else}}
107-
<NewSession @sendPrompt={{this.sendMessage}} />
107+
{{#if this.matrixService.isLoadingTimeline}}
108+
<LoadingIndicator
109+
@color='var(--boxel-light)'
110+
class='loading-indicator'
111+
/>
112+
{{else}}
113+
<NewSession @sendPrompt={{this.sendMessage}} />
114+
{{/if}}
108115
{{/each}}
109116
{{#if this.room}}
110117
{{#if this.showUnreadIndicator}}
@@ -154,12 +161,16 @@ export default class Room extends Component<Signature> {
154161
'Current card is shared automatically'
155162
'Topmost card is shared automatically'
156163
}}
164+
@disabled={{this.matrixService.isLoadingTimeline}}
157165
/>
158166
<LLMSelect
159167
@selected={{@roomResource.activeLLM}}
160168
@onChange={{@roomResource.activateLLM}}
161169
@options={{this.supportedLLMs}}
162-
@disabled={{@roomResource.isActivatingLLM}}
170+
@disabled={{(or
171+
@roomResource.isActivatingLLM
172+
this.matrixService.isLoadingTimeline
173+
)}}
163174
/>
164175
</div>
165176
</div>
@@ -213,6 +224,12 @@ export default class Room extends Component<Signature> {
213224
:deep(.ai-assistant-conversation > *:nth-last-of-type(2)) {
214225
padding-bottom: var(--boxel-sp-xl);
215226
}
227+
.loading-indicator {
228+
margin-top: auto;
229+
margin-bottom: auto;
230+
margin-left: auto;
231+
margin-right: auto;
232+
}
216233
</style>
217234
</template>
218235

@@ -798,7 +815,8 @@ export default class Room extends Component<Signature> {
798815
this.autoAttachedCards.size !== 0,
799816
) &&
800817
!!this.room &&
801-
!this.messages.some((m) => this.isPendingMessage(m))
818+
!this.messages.some((m) => this.isPendingMessage(m)) &&
819+
!this.matrixService.isLoadingTimeline
802820
);
803821
}
804822

packages/host/app/services/matrix-service.ts

+7-115
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { debounce } from '@ember/runloop';
44
import Service, { service } from '@ember/service';
55
import { cached, tracked } from '@glimmer/tracking';
66

7-
import { task, timeout, restartableTask } from 'ember-concurrency';
7+
import { restartableTask, task } from 'ember-concurrency';
88
import window from 'ember-window-mock';
99
import { cloneDeep } from 'lodash';
1010
import {
@@ -14,12 +14,7 @@ import {
1414
type EmittedEvents,
1515
type ISendEventResponse,
1616
} from 'matrix-js-sdk';
17-
import {
18-
SlidingSync,
19-
MSC3575List,
20-
SlidingSyncEvent,
21-
} from 'matrix-js-sdk/lib/sliding-sync';
22-
import { SlidingSyncState } from 'matrix-js-sdk/lib/sliding-sync';
17+
import { SlidingSync, MSC3575List } from 'matrix-js-sdk/lib/sliding-sync';
2318
import stringify from 'safe-stable-stringify';
2419
import { md5 } from 'super-fast-md5';
2520
import { TrackedMap } from 'tracked-built-ins';
@@ -123,7 +118,7 @@ const MAX_CARD_SIZE_KB = 60;
123118
const STATE_EVENTS_OF_INTEREST = ['m.room.create', 'm.room.name'];
124119
const SLIDING_SYNC_AI_ROOM_LIST_NAME = 'ai-room';
125120
const SLIDING_SYNC_AUTH_ROOM_LIST_NAME = 'auth-room';
126-
const SLIDING_SYNC_LIST_RANGE_SIZE = 2;
121+
const SLIDING_SYNC_LIST_RANGE_SIZE = 10;
127122
const SLIDING_SYNC_LIST_TIMELINE_LIMIT = 1;
128123

129124
const realmEventsLogger = logger('realm:events');
@@ -151,10 +146,6 @@ export default class MatrixService extends Service {
151146
@tracked private _currentRoomId: string | undefined;
152147
@tracked private timelineLoadingState: Map<string, boolean> =
153148
new TrackedMap();
154-
@tracked private currentAiRoomListRange = SLIDING_SYNC_LIST_RANGE_SIZE;
155-
@tracked private totalAiRooms?: number;
156-
@tracked private totalAuthRooms?: number;
157-
@tracked private currentAuthRoomListRange = SLIDING_SYNC_LIST_RANGE_SIZE;
158149

159150
profile = getMatrixProfile(this, () => this.userId);
160151

@@ -198,7 +189,7 @@ export default class MatrixService extends Service {
198189
set currentRoomId(value: string | undefined) {
199190
this._currentRoomId = value;
200191
if (value) {
201-
this.loadAllTimelineEvents(value);
192+
this.loadAllTimelineEvents.perform(value);
202193
window.localStorage.setItem(CurrentRoomIdPersistenceKey, value);
203194
} else {
204195
window.localStorage.removeItem(CurrentRoomIdPersistenceKey);
@@ -545,98 +536,9 @@ export default class MatrixService extends Service {
545536
3000,
546537
);
547538

548-
this.slidingSync.on(SlidingSyncEvent.Lifecycle, (state, response) => {
549-
if (state !== SlidingSyncState.Complete || !response) {
550-
return;
551-
}
552-
553-
// Handle AI rooms
554-
if (
555-
response.lists[SLIDING_SYNC_AI_ROOM_LIST_NAME]?.ops?.[0].op === 'SYNC'
556-
) {
557-
if (
558-
response.lists?.[SLIDING_SYNC_AI_ROOM_LIST_NAME]?.count !== undefined
559-
) {
560-
this.totalAiRooms =
561-
response.lists[SLIDING_SYNC_AI_ROOM_LIST_NAME].count;
562-
const currentRange =
563-
response.lists[SLIDING_SYNC_AI_ROOM_LIST_NAME].ops?.[0]?.range;
564-
565-
if (currentRange) {
566-
this.currentAiRoomListRange = currentRange[1];
567-
this.maybeLoadMoreAiRooms.perform();
568-
}
569-
}
570-
}
571-
572-
// Handle Auth rooms
573-
if (
574-
response.lists[SLIDING_SYNC_AUTH_ROOM_LIST_NAME]?.ops?.[0].op === 'SYNC'
575-
) {
576-
if (
577-
response.lists?.[SLIDING_SYNC_AUTH_ROOM_LIST_NAME]?.count !==
578-
undefined
579-
) {
580-
this.totalAuthRooms =
581-
response.lists[SLIDING_SYNC_AUTH_ROOM_LIST_NAME].count;
582-
const currentAuthRange =
583-
response.lists[SLIDING_SYNC_AUTH_ROOM_LIST_NAME].ops?.[0]?.range;
584-
585-
if (currentAuthRange) {
586-
this.currentAuthRoomListRange = currentAuthRange[1];
587-
this.maybeLoadMoreAuthRooms.perform();
588-
}
589-
}
590-
}
591-
});
592-
593539
return this.slidingSync;
594540
}
595541

596-
private maybeLoadMoreAiRooms = restartableTask(async () => {
597-
if (!this.totalAiRooms || !this.slidingSync) {
598-
return;
599-
}
600-
601-
while (this.currentAiRoomListRange < this.totalAiRooms) {
602-
const nextRange = Math.min(
603-
this.currentAiRoomListRange + 2,
604-
this.totalAiRooms,
605-
);
606-
607-
try {
608-
await this.slidingSync.setListRanges('ai-room', [[0, nextRange]]);
609-
this.currentAiRoomListRange = nextRange;
610-
await timeout(500);
611-
} catch (error) {
612-
console.error('Error expanding room range:', error);
613-
break;
614-
}
615-
}
616-
});
617-
618-
private maybeLoadMoreAuthRooms = restartableTask(async () => {
619-
if (!this.totalAuthRooms || !this.slidingSync) {
620-
return;
621-
}
622-
623-
while (this.currentAuthRoomListRange < this.totalAuthRooms) {
624-
const nextRange = Math.min(
625-
this.currentAuthRoomListRange + 2,
626-
this.totalAuthRooms,
627-
);
628-
629-
try {
630-
await this.slidingSync.setListRanges('auth-room', [[0, nextRange]]);
631-
this.currentAuthRoomListRange = nextRange;
632-
await timeout(500);
633-
} catch (error) {
634-
console.error('Error expanding auth room range:', error);
635-
break;
636-
}
637-
}
638-
});
639-
640542
private async loginToRealms() {
641543
// This is where we would actually load user-specific choices out of the
642544
// user's profile based on this.client.getUserId();
@@ -1270,7 +1172,7 @@ export default class MatrixService extends Service {
12701172
return await this.client.isUsernameAvailable(username);
12711173
}
12721174

1273-
private async loadAllTimelineEvents(roomId: string) {
1175+
private loadAllTimelineEvents = restartableTask(async (roomId: string) => {
12741176
let roomData = this.ensureRoomData(roomId);
12751177
let room = this.client.getRoom(roomId);
12761178

@@ -1282,25 +1184,15 @@ export default class MatrixService extends Service {
12821184
try {
12831185
while (room.oldState.paginationToken != null) {
12841186
await this.client.scrollback(room);
1285-
await timeout(1000);
12861187
let rs = room.getLiveTimeline().getState('f' as MatrixSDK.Direction);
12871188
if (rs) {
12881189
roomData.notifyRoomStateUpdated(rs);
12891190
}
12901191
}
1291-
1292-
const timeline = room.getLiveTimeline();
1293-
const events = timeline.getEvents();
1294-
for (let event of events) {
1295-
await this.processDecryptedEvent(this.buildEventForProcessing(event));
1296-
}
1297-
} catch (error) {
1298-
console.error('Error loading timeline events:', error);
1299-
throw error;
13001192
} finally {
13011193
this.timelineLoadingState.set(roomId, false);
13021194
}
1303-
}
1195+
});
13041196

13051197
get isLoadingTimeline() {
13061198
if (!this.currentRoomId) {
@@ -1575,7 +1467,7 @@ export default class MatrixService extends Service {
15751467
return;
15761468
}
15771469

1578-
let roomData = await this.getRoomData(roomId);
1470+
let roomData = this.getRoomData(roomId);
15791471
// patch in any missing room events--this will support dealing with local
15801472
// echoes, migrating older histories as well as handle any matrix syncing gaps
15811473
// that might occur

packages/host/tests/helpers/mock-matrix/_client.ts

+4
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,10 @@ export class MockClient implements ExtendedClient {
399399
return {
400400
getState: (_direction: MatrixSDK.Direction) =>
401401
this.serverState.getRoomStateUpdatePayload(roomId!),
402+
getEvents: () =>
403+
this.serverState
404+
.getRoomEvents(roomId!)
405+
.map((e) => new MatrixEvent(e)),
402406
};
403407
},
404408
} as MatrixSDK.Room;

packages/host/tests/helpers/mock-matrix/_sdk.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { MatrixEvent as MatrixEventClass } from 'matrix-js-sdk';
2+
13
import type { ExtendedMatrixSDK } from '@cardstack/host/services/matrix-sdk-loader';
24

35
import { MockClient } from './_client';
@@ -57,4 +59,10 @@ export class MockSDK implements PublicAPI<ExtendedMatrixSDK> {
5759
BeaconLiveness: 'RoomState.BeaconLiveness',
5860
Marker: 'RoomState.Marker',
5961
} as ExtendedMatrixSDK['RoomStateEvent'];
62+
63+
MatrixEvent = class MatrixEvent {
64+
constructor(event: any) {
65+
return new MatrixEventClass(event);
66+
}
67+
} as ExtendedMatrixSDK['MatrixEvent'];
6068
}

0 commit comments

Comments
 (0)