Merge pull request #6345 from matrix-org/t3chguy/ts/c1
						commit
						57f9b819b5
					
				|  | @ -154,7 +154,7 @@ export default class CallHandler extends EventEmitter { | |||
|     private supportsPstnProtocol = null; | ||||
|     private pstnSupportPrefixed = null; // True if the server only support the prefixed pstn protocol
 | ||||
|     private supportsSipNativeVirtual = null; // im.vector.protocol.sip_virtual and im.vector.protocol.sip_native
 | ||||
|     private pstnSupportCheckTimer: NodeJS.Timeout; // number actually because we're in the browser
 | ||||
|     private pstnSupportCheckTimer: number; | ||||
|     // For rooms we've been invited to, true if they're from virtual user, false if we've checked and they aren't.
 | ||||
|     private invitedRoomsAreVirtual = new Map<string, boolean>(); | ||||
|     private invitedRoomCheckInProgress = false; | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ import { | |||
|     UploadStartedPayload, | ||||
| } from "./dispatcher/payloads/UploadPayload"; | ||||
| import { IUpload } from "./models/IUpload"; | ||||
| import { IImageInfo } from "matrix-js-sdk/src/@types/partials"; | ||||
| import { IAbortablePromise, IImageInfo } from "matrix-js-sdk/src/@types/partials"; | ||||
| 
 | ||||
| const MAX_WIDTH = 800; | ||||
| const MAX_HEIGHT = 600; | ||||
|  | @ -85,10 +85,6 @@ interface IThumbnail { | |||
|     thumbnail: Blob; | ||||
| } | ||||
| 
 | ||||
| interface IAbortablePromise<T> extends Promise<T> { | ||||
|     abort(): void; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Create a thumbnail for a image DOM element. | ||||
|  * The image will be smaller than MAX_WIDTH and MAX_HEIGHT. | ||||
|  | @ -333,7 +329,7 @@ export function uploadFile( | |||
|     roomId: string, | ||||
|     file: File | Blob, | ||||
|     progressHandler?: any, // TODO: Types
 | ||||
| ): Promise<{url?: string, file?: any}> { // TODO: Types
 | ||||
| ): IAbortablePromise<{url?: string, file?: any}> { // TODO: Types
 | ||||
|     let canceled = false; | ||||
|     if (matrixClient.isRoomEncrypted(roomId)) { | ||||
|         // If the room is encrypted then encrypt the file before uploading it.
 | ||||
|  | @ -365,8 +361,8 @@ export function uploadFile( | |||
|                 encryptInfo.mimetype = file.type; | ||||
|             } | ||||
|             return { "file": encryptInfo }; | ||||
|         }); | ||||
|         (prom as IAbortablePromise<any>).abort = () => { | ||||
|         }) as IAbortablePromise<{ file: any }>; | ||||
|         prom.abort = () => { | ||||
|             canceled = true; | ||||
|             if (uploadPromise) matrixClient.cancelUpload(uploadPromise); | ||||
|         }; | ||||
|  | @ -379,8 +375,8 @@ export function uploadFile( | |||
|             if (canceled) throw new UploadCanceledError(); | ||||
|             // If the attachment isn't encrypted then include the URL directly.
 | ||||
|             return { url }; | ||||
|         }); | ||||
|         (promise1 as any).abort = () => { | ||||
|         }) as IAbortablePromise<{ url: string }>; | ||||
|         promise1.abort = () => { | ||||
|             canceled = true; | ||||
|             matrixClient.cancelUpload(basePromise); | ||||
|         }; | ||||
|  | @ -551,10 +547,10 @@ export default class ContentMessages { | |||
|                 content.msgtype = 'm.file'; | ||||
|                 resolve(); | ||||
|             } | ||||
|         }); | ||||
|         }) as IAbortablePromise<void>; | ||||
| 
 | ||||
|         // create temporary abort handler for before the actual upload gets passed off to js-sdk
 | ||||
|         (prom as IAbortablePromise<any>).abort = () => { | ||||
|         prom.abort = () => { | ||||
|             upload.canceled = true; | ||||
|         }; | ||||
| 
 | ||||
|  | @ -583,9 +579,7 @@ export default class ContentMessages { | |||
|             // XXX: upload.promise must be the promise that
 | ||||
|             // is returned by uploadFile as it has an abort()
 | ||||
|             // method hacked onto it.
 | ||||
|             upload.promise = uploadFile( | ||||
|                 matrixClient, roomId, file, onProgress, | ||||
|             ); | ||||
|             upload.promise = uploadFile(matrixClient, roomId, file, onProgress); | ||||
|             return upload.promise.then(function(result) { | ||||
|                 content.file = result.file; | ||||
|                 content.url = result.url; | ||||
|  |  | |||
|  | @ -364,8 +364,8 @@ export default class CountlyAnalytics { | |||
| 
 | ||||
|     private initTime = CountlyAnalytics.getTimestamp(); | ||||
|     private firstPage = true; | ||||
|     private heartbeatIntervalId: NodeJS.Timeout; | ||||
|     private activityIntervalId: NodeJS.Timeout; | ||||
|     private heartbeatIntervalId: number; | ||||
|     private activityIntervalId: number; | ||||
|     private trackTime = true; | ||||
|     private lastBeat: number; | ||||
|     private storedDuration = 0; | ||||
|  |  | |||
|  | @ -46,8 +46,8 @@ export class DecryptionFailureTracker { | |||
|     }; | ||||
| 
 | ||||
|     // Set to an interval ID when `start` is called
 | ||||
|     public checkInterval: NodeJS.Timeout = null; | ||||
|     public trackInterval: NodeJS.Timeout = null; | ||||
|     public checkInterval: number = null; | ||||
|     public trackInterval: number = null; | ||||
| 
 | ||||
|     // Spread the load on `Analytics` by tracking at a low frequency, `TRACK_INTERVAL_MS`.
 | ||||
|     static TRACK_INTERVAL_MS = 60000; | ||||
|  |  | |||
|  | @ -17,8 +17,8 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| import { ICreateClientOpts } from 'matrix-js-sdk/src/matrix'; | ||||
| import { MatrixClient } from 'matrix-js-sdk/src/client'; | ||||
| import { ICreateClientOpts, PendingEventOrdering } from 'matrix-js-sdk/src/matrix'; | ||||
| import { IStartClientOpts, MatrixClient } from 'matrix-js-sdk/src/client'; | ||||
| import { MemoryStore } from 'matrix-js-sdk/src/store/memory'; | ||||
| import * as utils from 'matrix-js-sdk/src/utils'; | ||||
| import { EventTimeline } from 'matrix-js-sdk/src/models/event-timeline'; | ||||
|  | @ -47,16 +47,8 @@ export interface IMatrixClientCreds { | |||
|     freshLogin?: boolean; | ||||
| } | ||||
| 
 | ||||
| // TODO: Move this to the js-sdk
 | ||||
| export interface IOpts { | ||||
|     initialSyncLimit?: number; | ||||
|     pendingEventOrdering?: "detached" | "chronological"; | ||||
|     lazyLoadMembers?: boolean; | ||||
|     clientWellKnownPollPeriod?: number; | ||||
| } | ||||
| 
 | ||||
| export interface IMatrixClientPeg { | ||||
|     opts: IOpts; | ||||
|     opts: IStartClientOpts; | ||||
| 
 | ||||
|     /** | ||||
|      * Sets the script href passed to the IndexedDB web worker | ||||
|  | @ -127,7 +119,7 @@ class _MatrixClientPeg implements IMatrixClientPeg { | |||
|     // client is started in 'start'. These can be altered
 | ||||
|     // at any time up to after the 'will_start_client'
 | ||||
|     // event is finished processing.
 | ||||
|     public opts: IOpts = { | ||||
|     public opts: IStartClientOpts = { | ||||
|         initialSyncLimit: 20, | ||||
|     }; | ||||
| 
 | ||||
|  | @ -231,7 +223,7 @@ class _MatrixClientPeg implements IMatrixClientPeg { | |||
| 
 | ||||
|         const opts = utils.deepCopy(this.opts); | ||||
|         // the react sdk doesn't work without this, so don't allow
 | ||||
|         opts.pendingEventOrdering = "detached"; | ||||
|         opts.pendingEventOrdering = PendingEventOrdering.Detached; | ||||
|         opts.lazyLoadMembers = true; | ||||
|         opts.clientWellKnownPollPeriod = 2 * 60 * 60; // 2 hours
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -84,10 +84,8 @@ export function guessAndSetDMRoom(room: Room, isDirect: boolean): Promise<void> | |||
|                    this room as a DM room | ||||
|  * @returns {object} A promise | ||||
|  */ | ||||
| export function setDMRoom(roomId: string, userId: string): Promise<void> { | ||||
|     if (MatrixClientPeg.get().isGuest()) { | ||||
|         return Promise.resolve(); | ||||
|     } | ||||
| export async function setDMRoom(roomId: string, userId: string): Promise<void> { | ||||
|     if (MatrixClientPeg.get().isGuest()) return; | ||||
| 
 | ||||
|     const mDirectEvent = MatrixClientPeg.get().getAccountData('m.direct'); | ||||
|     let dmRoomMap = {}; | ||||
|  | @ -116,7 +114,7 @@ export function setDMRoom(roomId: string, userId: string): Promise<void> { | |||
|         dmRoomMap[userId] = roomList; | ||||
|     } | ||||
| 
 | ||||
|     return MatrixClientPeg.get().setAccountData('m.direct', dmRoomMap); | ||||
|     await MatrixClientPeg.get().setAccountData('m.direct', dmRoomMap); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| /* | ||||
| Copyright 2019 The Matrix.org Foundation C.I.C. | ||||
| Copyright 2019 - 2021 The Matrix.org Foundation C.I.C. | ||||
| 
 | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
|  | @ -14,26 +14,42 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| import { | ||||
|     IResultRoomEvents, | ||||
|     ISearchRequestBody, | ||||
|     ISearchResponse, | ||||
|     ISearchResult, | ||||
|     ISearchResults, | ||||
|     SearchOrderBy, | ||||
| } from "matrix-js-sdk/src/@types/search"; | ||||
| import { IRoomEventFilter } from "matrix-js-sdk/src/filter"; | ||||
| import { EventType } from "matrix-js-sdk/src/@types/event"; | ||||
| 
 | ||||
| import { ISearchArgs } from "./indexing/BaseEventIndexManager"; | ||||
| import EventIndexPeg from "./indexing/EventIndexPeg"; | ||||
| import { MatrixClientPeg } from "./MatrixClientPeg"; | ||||
| import { SearchResult } from "matrix-js-sdk/src/models/search-result"; | ||||
| 
 | ||||
| const SEARCH_LIMIT = 10; | ||||
| 
 | ||||
| async function serverSideSearch(term, roomId = undefined) { | ||||
| async function serverSideSearch( | ||||
|     term: string, | ||||
|     roomId: string = undefined, | ||||
| ): Promise<{ response: ISearchResponse, query: ISearchRequestBody }> { | ||||
|     const client = MatrixClientPeg.get(); | ||||
| 
 | ||||
|     const filter = { | ||||
|     const filter: IRoomEventFilter = { | ||||
|         limit: SEARCH_LIMIT, | ||||
|     }; | ||||
| 
 | ||||
|     if (roomId !== undefined) filter.rooms = [roomId]; | ||||
| 
 | ||||
|     const body = { | ||||
|     const body: ISearchRequestBody = { | ||||
|         search_categories: { | ||||
|             room_events: { | ||||
|                 search_term: term, | ||||
|                 filter: filter, | ||||
|                 order_by: "recent", | ||||
|                 order_by: SearchOrderBy.Recent, | ||||
|                 event_context: { | ||||
|                     before_limit: 1, | ||||
|                     after_limit: 1, | ||||
|  | @ -45,31 +61,26 @@ async function serverSideSearch(term, roomId = undefined) { | |||
| 
 | ||||
|     const response = await client.search({ body: body }); | ||||
| 
 | ||||
|     const result = { | ||||
|         response: response, | ||||
|         query: body, | ||||
|     }; | ||||
| 
 | ||||
|     return result; | ||||
|     return { response, query: body }; | ||||
| } | ||||
| 
 | ||||
| async function serverSideSearchProcess(term, roomId = undefined) { | ||||
| async function serverSideSearchProcess(term: string, roomId: string = undefined): Promise<ISearchResults> { | ||||
|     const client = MatrixClientPeg.get(); | ||||
|     const result = await serverSideSearch(term, roomId); | ||||
| 
 | ||||
|     // The js-sdk method backPaginateRoomEventsSearch() uses _query internally
 | ||||
|     // so we're reusing the concept here since we wan't to delegate the
 | ||||
|     // so we're reusing the concept here since we want to delegate the
 | ||||
|     // pagination back to backPaginateRoomEventsSearch() in some cases.
 | ||||
|     const searchResult = { | ||||
|     const searchResults: ISearchResults = { | ||||
|         _query: result.query, | ||||
|         results: [], | ||||
|         highlights: [], | ||||
|     }; | ||||
| 
 | ||||
|     return client.processRoomEventsSearch(searchResult, result.response); | ||||
|     return client.processRoomEventsSearch(searchResults, result.response); | ||||
| } | ||||
| 
 | ||||
| function compareEvents(a, b) { | ||||
| function compareEvents(a: ISearchResult, b: ISearchResult): number { | ||||
|     const aEvent = a.result; | ||||
|     const bEvent = b.result; | ||||
| 
 | ||||
|  | @ -79,7 +90,7 @@ function compareEvents(a, b) { | |||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| async function combinedSearch(searchTerm) { | ||||
| async function combinedSearch(searchTerm: string): Promise<ISearchResults> { | ||||
|     const client = MatrixClientPeg.get(); | ||||
| 
 | ||||
|     // Create two promises, one for the local search, one for the
 | ||||
|  | @ -111,10 +122,10 @@ async function combinedSearch(searchTerm) { | |||
|     // returns since that one can be either a server-side one, a local one or a
 | ||||
|     // fake one to fetch the remaining cached events. See the docs for
 | ||||
|     // combineEvents() for an explanation why we need to cache events.
 | ||||
|     const emptyResult = { | ||||
|     const emptyResult: ISeshatSearchResults = { | ||||
|         seshatQuery: localQuery, | ||||
|         _query: serverQuery, | ||||
|         serverSideNextBatch: serverResponse.next_batch, | ||||
|         serverSideNextBatch: serverResponse.search_categories.room_events.next_batch, | ||||
|         cachedEvents: [], | ||||
|         oldestEventFrom: "server", | ||||
|         results: [], | ||||
|  | @ -125,7 +136,7 @@ async function combinedSearch(searchTerm) { | |||
|     const combinedResult = combineResponses(emptyResult, localResponse, serverResponse.search_categories.room_events); | ||||
| 
 | ||||
|     // Let the client process the combined result.
 | ||||
|     const response = { | ||||
|     const response: ISearchResponse = { | ||||
|         search_categories: { | ||||
|             room_events: combinedResult, | ||||
|         }, | ||||
|  | @ -139,10 +150,14 @@ async function combinedSearch(searchTerm) { | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| async function localSearch(searchTerm, roomId = undefined, processResult = true) { | ||||
| async function localSearch( | ||||
|     searchTerm: string, | ||||
|     roomId: string = undefined, | ||||
|     processResult = true, | ||||
| ): Promise<{ response: IResultRoomEvents, query: ISearchArgs }> { | ||||
|     const eventIndex = EventIndexPeg.get(); | ||||
| 
 | ||||
|     const searchArgs = { | ||||
|     const searchArgs: ISearchArgs = { | ||||
|         search_term: searchTerm, | ||||
|         before_limit: 1, | ||||
|         after_limit: 1, | ||||
|  | @ -167,11 +182,18 @@ async function localSearch(searchTerm, roomId = undefined, processResult = true) | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| async function localSearchProcess(searchTerm, roomId = undefined) { | ||||
| export interface ISeshatSearchResults extends ISearchResults { | ||||
|     seshatQuery?: ISearchArgs; | ||||
|     cachedEvents?: ISearchResult[]; | ||||
|     oldestEventFrom?: "local" | "server"; | ||||
|     serverSideNextBatch?: string; | ||||
| } | ||||
| 
 | ||||
| async function localSearchProcess(searchTerm: string, roomId: string = undefined): Promise<ISeshatSearchResults> { | ||||
|     const emptyResult = { | ||||
|         results: [], | ||||
|         highlights: [], | ||||
|     }; | ||||
|     } as ISeshatSearchResults; | ||||
| 
 | ||||
|     if (searchTerm === "") return emptyResult; | ||||
| 
 | ||||
|  | @ -179,7 +201,7 @@ async function localSearchProcess(searchTerm, roomId = undefined) { | |||
| 
 | ||||
|     emptyResult.seshatQuery = result.query; | ||||
| 
 | ||||
|     const response = { | ||||
|     const response: ISearchResponse = { | ||||
|         search_categories: { | ||||
|             room_events: result.response, | ||||
|         }, | ||||
|  | @ -192,7 +214,7 @@ async function localSearchProcess(searchTerm, roomId = undefined) { | |||
|     return processedResult; | ||||
| } | ||||
| 
 | ||||
| async function localPagination(searchResult) { | ||||
| async function localPagination(searchResult: ISeshatSearchResults): Promise<ISeshatSearchResults> { | ||||
|     const eventIndex = EventIndexPeg.get(); | ||||
| 
 | ||||
|     const searchArgs = searchResult.seshatQuery; | ||||
|  | @ -221,10 +243,10 @@ async function localPagination(searchResult) { | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| function compareOldestEvents(firstResults, secondResults) { | ||||
| function compareOldestEvents(firstResults: ISearchResult[], secondResults: ISearchResult[]): number { | ||||
|     try { | ||||
|         const oldestFirstEvent = firstResults.results[firstResults.results.length - 1].result; | ||||
|         const oldestSecondEvent = secondResults.results[secondResults.results.length - 1].result; | ||||
|         const oldestFirstEvent = firstResults[firstResults.length - 1].result; | ||||
|         const oldestSecondEvent = secondResults[secondResults.length - 1].result; | ||||
| 
 | ||||
|         if (oldestFirstEvent.origin_server_ts <= oldestSecondEvent.origin_server_ts) { | ||||
|             return -1; | ||||
|  | @ -236,7 +258,12 @@ function compareOldestEvents(firstResults, secondResults) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| function combineEventSources(previousSearchResult, response, a, b) { | ||||
| function combineEventSources( | ||||
|     previousSearchResult: ISeshatSearchResults, | ||||
|     response: IResultRoomEvents, | ||||
|     a: ISearchResult[], | ||||
|     b: ISearchResult[], | ||||
| ): void { | ||||
|     // Merge event sources and sort the events.
 | ||||
|     const combinedEvents = a.concat(b).sort(compareEvents); | ||||
|     // Put half of the events in the response, and cache the other half.
 | ||||
|  | @ -353,8 +380,12 @@ function combineEventSources(previousSearchResult, response, a, b) { | |||
|  * different event sources. | ||||
|  * | ||||
|  */ | ||||
| function combineEvents(previousSearchResult, localEvents = undefined, serverEvents = undefined) { | ||||
|     const response = {}; | ||||
| function combineEvents( | ||||
|     previousSearchResult: ISeshatSearchResults, | ||||
|     localEvents: IResultRoomEvents = undefined, | ||||
|     serverEvents: IResultRoomEvents = undefined, | ||||
| ): IResultRoomEvents { | ||||
|     const response = {} as IResultRoomEvents; | ||||
| 
 | ||||
|     const cachedEvents = previousSearchResult.cachedEvents; | ||||
|     let oldestEventFrom = previousSearchResult.oldestEventFrom; | ||||
|  | @ -364,7 +395,7 @@ function combineEvents(previousSearchResult, localEvents = undefined, serverEven | |||
|         // This is a first search call, combine the events from the server and
 | ||||
|         // the local index. Note where our oldest event came from, we shall
 | ||||
|         // fetch the next batch of events from the other source.
 | ||||
|         if (compareOldestEvents(localEvents, serverEvents) < 0) { | ||||
|         if (compareOldestEvents(localEvents.results, serverEvents.results) < 0) { | ||||
|             oldestEventFrom = "local"; | ||||
|         } | ||||
| 
 | ||||
|  | @ -375,7 +406,7 @@ function combineEvents(previousSearchResult, localEvents = undefined, serverEven | |||
|         // meaning that our oldest event was on the server.
 | ||||
|         // Change the source of the oldest event if our local event is older
 | ||||
|         // than the cached one.
 | ||||
|         if (compareOldestEvents(localEvents, cachedEvents) < 0) { | ||||
|         if (compareOldestEvents(localEvents.results, cachedEvents) < 0) { | ||||
|             oldestEventFrom = "local"; | ||||
|         } | ||||
|         combineEventSources(previousSearchResult, response, localEvents.results, cachedEvents); | ||||
|  | @ -384,7 +415,7 @@ function combineEvents(previousSearchResult, localEvents = undefined, serverEven | |||
|         // meaning that our oldest event was in the local index.
 | ||||
|         // Change the source of the oldest event if our server event is older
 | ||||
|         // than the cached one.
 | ||||
|         if (compareOldestEvents(serverEvents, cachedEvents) < 0) { | ||||
|         if (compareOldestEvents(serverEvents.results, cachedEvents) < 0) { | ||||
|             oldestEventFrom = "server"; | ||||
|         } | ||||
|         combineEventSources(previousSearchResult, response, serverEvents.results, cachedEvents); | ||||
|  | @ -412,7 +443,11 @@ function combineEvents(previousSearchResult, localEvents = undefined, serverEven | |||
|  * @return {object} A response object that combines the events from the | ||||
|  * different event sources. | ||||
|  */ | ||||
| function combineResponses(previousSearchResult, localEvents = undefined, serverEvents = undefined) { | ||||
| function combineResponses( | ||||
|     previousSearchResult: ISeshatSearchResults, | ||||
|     localEvents: IResultRoomEvents = undefined, | ||||
|     serverEvents: IResultRoomEvents = undefined, | ||||
| ): IResultRoomEvents { | ||||
|     // Combine our events first.
 | ||||
|     const response = combineEvents(previousSearchResult, localEvents, serverEvents); | ||||
| 
 | ||||
|  | @ -454,42 +489,51 @@ function combineResponses(previousSearchResult, localEvents = undefined, serverE | |||
|     return response; | ||||
| } | ||||
| 
 | ||||
| function restoreEncryptionInfo(searchResultSlice = []) { | ||||
| interface IEncryptedSeshatEvent { | ||||
|     curve25519Key: string; | ||||
|     ed25519Key: string; | ||||
|     algorithm: string; | ||||
|     forwardingCurve25519KeyChain: string[]; | ||||
| } | ||||
| 
 | ||||
| function restoreEncryptionInfo(searchResultSlice: SearchResult[] = []): void { | ||||
|     for (let i = 0; i < searchResultSlice.length; i++) { | ||||
|         const timeline = searchResultSlice[i].context.getTimeline(); | ||||
| 
 | ||||
|         for (let j = 0; j < timeline.length; j++) { | ||||
|             const ev = timeline[j]; | ||||
|             const mxEv = timeline[j]; | ||||
|             const ev = mxEv.event as IEncryptedSeshatEvent; | ||||
| 
 | ||||
|             if (ev.event.curve25519Key) { | ||||
|                 ev.makeEncrypted( | ||||
|                     "m.room.encrypted", | ||||
|                     { algorithm: ev.event.algorithm }, | ||||
|                     ev.event.curve25519Key, | ||||
|                     ev.event.ed25519Key, | ||||
|             if (ev.curve25519Key) { | ||||
|                 mxEv.makeEncrypted( | ||||
|                     EventType.RoomMessageEncrypted, | ||||
|                     { algorithm: ev.algorithm }, | ||||
|                     ev.curve25519Key, | ||||
|                     ev.ed25519Key, | ||||
|                 ); | ||||
|                 ev.forwardingCurve25519KeyChain = ev.event.forwardingCurve25519KeyChain; | ||||
|                 // @ts-ignore
 | ||||
|                 mxEv.forwardingCurve25519KeyChain = ev.forwardingCurve25519KeyChain; | ||||
| 
 | ||||
|                 delete ev.event.curve25519Key; | ||||
|                 delete ev.event.ed25519Key; | ||||
|                 delete ev.event.algorithm; | ||||
|                 delete ev.event.forwardingCurve25519KeyChain; | ||||
|                 delete ev.curve25519Key; | ||||
|                 delete ev.ed25519Key; | ||||
|                 delete ev.algorithm; | ||||
|                 delete ev.forwardingCurve25519KeyChain; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| async function combinedPagination(searchResult) { | ||||
| async function combinedPagination(searchResult: ISeshatSearchResults): Promise<ISeshatSearchResults> { | ||||
|     const eventIndex = EventIndexPeg.get(); | ||||
|     const client = MatrixClientPeg.get(); | ||||
| 
 | ||||
|     const searchArgs = searchResult.seshatQuery; | ||||
|     const oldestEventFrom = searchResult.oldestEventFrom; | ||||
| 
 | ||||
|     let localResult; | ||||
|     let serverSideResult; | ||||
|     let localResult: IResultRoomEvents; | ||||
|     let serverSideResult: ISearchResponse; | ||||
| 
 | ||||
|     // Fetch events from the local index if we have a token for itand if it's
 | ||||
|     // Fetch events from the local index if we have a token for it and if it's
 | ||||
|     // the local indexes turn or the server has exhausted its results.
 | ||||
|     if (searchArgs.next_batch && (!searchResult.serverSideNextBatch || oldestEventFrom === "server")) { | ||||
|         localResult = await eventIndex.search(searchArgs); | ||||
|  | @ -502,7 +546,7 @@ async function combinedPagination(searchResult) { | |||
|         serverSideResult = await client.search(body); | ||||
|     } | ||||
| 
 | ||||
|     let serverEvents; | ||||
|     let serverEvents: IResultRoomEvents; | ||||
| 
 | ||||
|     if (serverSideResult) { | ||||
|         serverEvents = serverSideResult.search_categories.room_events; | ||||
|  | @ -532,8 +576,8 @@ async function combinedPagination(searchResult) { | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| function eventIndexSearch(term, roomId = undefined) { | ||||
|     let searchPromise; | ||||
| function eventIndexSearch(term: string, roomId: string = undefined): Promise<ISearchResults> { | ||||
|     let searchPromise: Promise<ISearchResults>; | ||||
| 
 | ||||
|     if (roomId !== undefined) { | ||||
|         if (MatrixClientPeg.get().isRoomEncrypted(roomId)) { | ||||
|  | @ -554,7 +598,7 @@ function eventIndexSearch(term, roomId = undefined) { | |||
|     return searchPromise; | ||||
| } | ||||
| 
 | ||||
| function eventIndexSearchPagination(searchResult) { | ||||
| function eventIndexSearchPagination(searchResult: ISeshatSearchResults): Promise<ISeshatSearchResults> { | ||||
|     const client = MatrixClientPeg.get(); | ||||
| 
 | ||||
|     const seshatQuery = searchResult.seshatQuery; | ||||
|  | @ -580,7 +624,7 @@ function eventIndexSearchPagination(searchResult) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| export function searchPagination(searchResult) { | ||||
| export function searchPagination(searchResult: ISearchResults): Promise<ISearchResults> { | ||||
|     const eventIndex = EventIndexPeg.get(); | ||||
|     const client = MatrixClientPeg.get(); | ||||
| 
 | ||||
|  | @ -590,7 +634,7 @@ export function searchPagination(searchResult) { | |||
|     else return eventIndexSearchPagination(searchResult); | ||||
| } | ||||
| 
 | ||||
| export default function eventSearch(term, roomId = undefined) { | ||||
| export default function eventSearch(term: string, roomId: string = undefined): Promise<ISearchResults> { | ||||
|     const eventIndex = EventIndexPeg.get(); | ||||
| 
 | ||||
|     if (eventIndex === null) return serverSideSearchProcess(term, roomId); | ||||
|  | @ -251,7 +251,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> { | |||
|     private pageChanging: boolean; | ||||
|     private tokenLogin?: boolean; | ||||
|     private accountPassword?: string; | ||||
|     private accountPasswordTimer?: NodeJS.Timeout; | ||||
|     private accountPasswordTimer?: number; | ||||
|     private focusComposer: boolean; | ||||
|     private subTitleStatus: string; | ||||
|     private prevWindowWidth: number; | ||||
|  |  | |||
|  | @ -16,6 +16,9 @@ limitations under the License. | |||
| */ | ||||
| 
 | ||||
| import React from "react"; | ||||
| import { IFieldType, IInstance, IProtocol, IPublicRoomsChunkRoom } from "matrix-js-sdk/src/client"; | ||||
| import { Visibility } from "matrix-js-sdk/src/@types/partials"; | ||||
| import { IRoomDirectoryOptions } from "matrix-js-sdk/src/@types/requests"; | ||||
| 
 | ||||
| import { MatrixClientPeg } from "../../MatrixClientPeg"; | ||||
| import dis from "../../dispatcher/dispatcher"; | ||||
|  | @ -25,7 +28,7 @@ import { _t } from '../../languageHandler'; | |||
| import SdkConfig from '../../SdkConfig'; | ||||
| import { instanceForInstanceId, protocolNameForInstanceId } from '../../utils/DirectoryUtils'; | ||||
| import Analytics from '../../Analytics'; | ||||
| import { ALL_ROOMS, IFieldType, IInstance, IProtocol, Protocols } from "../views/directory/NetworkDropdown"; | ||||
| import NetworkDropdown, { ALL_ROOMS, Protocols } from "../views/directory/NetworkDropdown"; | ||||
| import SettingsStore from "../../settings/SettingsStore"; | ||||
| import GroupFilterOrderStore from "../../stores/GroupFilterOrderStore"; | ||||
| import GroupStore from "../../stores/GroupStore"; | ||||
|  | @ -40,7 +43,6 @@ import ErrorDialog from "../views/dialogs/ErrorDialog"; | |||
| import QuestionDialog from "../views/dialogs/QuestionDialog"; | ||||
| import BaseDialog from "../views/dialogs/BaseDialog"; | ||||
| import DirectorySearchBox from "../views/elements/DirectorySearchBox"; | ||||
| import NetworkDropdown from "../views/directory/NetworkDropdown"; | ||||
| import ScrollPanel from "./ScrollPanel"; | ||||
| import Spinner from "../views/elements/Spinner"; | ||||
| import { ActionPayload } from "../../dispatcher/payloads"; | ||||
|  | @ -61,7 +63,7 @@ interface IProps extends IDialogProps { | |||
| } | ||||
| 
 | ||||
| interface IState { | ||||
|     publicRooms: IRoom[]; | ||||
|     publicRooms: IPublicRoomsChunkRoom[]; | ||||
|     loading: boolean; | ||||
|     protocolsLoading: boolean; | ||||
|     error?: string; | ||||
|  | @ -72,35 +74,12 @@ interface IState { | |||
|     communityName?: string; | ||||
| } | ||||
| 
 | ||||
| /* eslint-disable camelcase */ | ||||
| interface IRoom { | ||||
|     room_id: string; | ||||
|     name?: string; | ||||
|     avatar_url?: string; | ||||
|     topic?: string; | ||||
|     canonical_alias?: string; | ||||
|     aliases?: string[]; | ||||
|     world_readable: boolean; | ||||
|     guest_can_join: boolean; | ||||
|     num_joined_members: number; | ||||
| } | ||||
| 
 | ||||
| interface IPublicRoomsRequest { | ||||
|     limit?: number; | ||||
|     since?: string; | ||||
|     server?: string; | ||||
|     filter?: object; | ||||
|     include_all_networks?: boolean; | ||||
|     third_party_instance_id?: string; | ||||
| } | ||||
| /* eslint-enable camelcase */ | ||||
| 
 | ||||
| @replaceableComponent("structures.RoomDirectory") | ||||
| export default class RoomDirectory extends React.Component<IProps, IState> { | ||||
|     private readonly startTime: number; | ||||
|     private unmounted = false; | ||||
|     private nextBatch: string = null; | ||||
|     private filterTimeout: NodeJS.Timeout; | ||||
|     private filterTimeout: number; | ||||
|     private protocols: Protocols; | ||||
| 
 | ||||
|     constructor(props) { | ||||
|  | @ -253,7 +232,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> { | |||
|         // remember the next batch token when we sent the request
 | ||||
|         // too. If it's changed, appending to the list will corrupt it.
 | ||||
|         const nextBatch = this.nextBatch; | ||||
|         const opts: IPublicRoomsRequest = { limit: 20 }; | ||||
|         const opts: IRoomDirectoryOptions = { limit: 20 }; | ||||
|         if (roomServer != MatrixClientPeg.getHomeserverName()) { | ||||
|             opts.server = roomServer; | ||||
|         } | ||||
|  | @ -326,7 +305,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> { | |||
|      * HS admins to do this through the RoomSettings interface, but | ||||
|      * this needs SPEC-417. | ||||
|      */ | ||||
|     private removeFromDirectory(room: IRoom) { | ||||
|     private removeFromDirectory(room: IPublicRoomsChunkRoom) { | ||||
|         const alias = getDisplayAliasForRoom(room); | ||||
|         const name = room.name || alias || _t('Unnamed room'); | ||||
| 
 | ||||
|  | @ -346,7 +325,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> { | |||
|                 const modal = Modal.createDialog(Spinner); | ||||
|                 let step = _t('remove %(name)s from the directory.', { name: name }); | ||||
| 
 | ||||
|                 MatrixClientPeg.get().setRoomDirectoryVisibility(room.room_id, 'private').then(() => { | ||||
|                 MatrixClientPeg.get().setRoomDirectoryVisibility(room.room_id, Visibility.Private).then(() => { | ||||
|                     if (!alias) return; | ||||
|                     step = _t('delete the address.'); | ||||
|                     return MatrixClientPeg.get().deleteAlias(alias); | ||||
|  | @ -368,7 +347,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> { | |||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private onRoomClicked = (room: IRoom, ev: ButtonEvent) => { | ||||
|     private onRoomClicked = (room: IPublicRoomsChunkRoom, ev: ButtonEvent) => { | ||||
|         // If room was shift-clicked, remove it from the room directory
 | ||||
|         if (ev.shiftKey && !this.state.selectedCommunityId) { | ||||
|             ev.preventDefault(); | ||||
|  | @ -481,17 +460,17 @@ export default class RoomDirectory extends React.Component<IProps, IState> { | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     private onPreviewClick = (ev: ButtonEvent, room: IRoom) => { | ||||
|     private onPreviewClick = (ev: ButtonEvent, room: IPublicRoomsChunkRoom) => { | ||||
|         this.showRoom(room, null, false, true); | ||||
|         ev.stopPropagation(); | ||||
|     }; | ||||
| 
 | ||||
|     private onViewClick = (ev: ButtonEvent, room: IRoom) => { | ||||
|     private onViewClick = (ev: ButtonEvent, room: IPublicRoomsChunkRoom) => { | ||||
|         this.showRoom(room); | ||||
|         ev.stopPropagation(); | ||||
|     }; | ||||
| 
 | ||||
|     private onJoinClick = (ev: ButtonEvent, room: IRoom) => { | ||||
|     private onJoinClick = (ev: ButtonEvent, room: IPublicRoomsChunkRoom) => { | ||||
|         this.showRoom(room, null, true); | ||||
|         ev.stopPropagation(); | ||||
|     }; | ||||
|  | @ -509,7 +488,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> { | |||
|         this.showRoom(null, alias, autoJoin); | ||||
|     } | ||||
| 
 | ||||
|     private showRoom(room: IRoom, roomAlias?: string, autoJoin = false, shouldPeek = false) { | ||||
|     private showRoom(room: IPublicRoomsChunkRoom, roomAlias?: string, autoJoin = false, shouldPeek = false) { | ||||
|         this.onFinished(); | ||||
|         const payload: ActionPayload = { | ||||
|             action: 'view_room', | ||||
|  | @ -558,7 +537,7 @@ export default class RoomDirectory extends React.Component<IProps, IState> { | |||
|         dis.dispatch(payload); | ||||
|     } | ||||
| 
 | ||||
|     private createRoomCells(room: IRoom) { | ||||
|     private createRoomCells(room: IPublicRoomsChunkRoom) { | ||||
|         const client = MatrixClientPeg.get(); | ||||
|         const clientRoom = client.getRoom(room.room_id); | ||||
|         const hasJoinedRoom = clientRoom && clientRoom.getMyMembership() === "join"; | ||||
|  | @ -854,6 +833,6 @@ export default class RoomDirectory extends React.Component<IProps, IState> { | |||
| 
 | ||||
| // Similar to matrix-react-sdk's MatrixTools.getDisplayAliasForRoom
 | ||||
| // but works with the objects we get from the public room list
 | ||||
| function getDisplayAliasForRoom(room: IRoom) { | ||||
| function getDisplayAliasForRoom(room: IPublicRoomsChunkRoom) { | ||||
|     return getDisplayAliasForAliasSet(room.canonical_alias, room.aliases); | ||||
| } | ||||
|  |  | |||
|  | @ -25,8 +25,8 @@ import React, { createRef } from 'react'; | |||
| import classNames from 'classnames'; | ||||
| import { IRecommendedVersion, NotificationCountType, Room } from "matrix-js-sdk/src/models/room"; | ||||
| import { MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||||
| import { SearchResult } from "matrix-js-sdk/src/models/search-result"; | ||||
| import { EventSubscription } from "fbemitter"; | ||||
| import { ISearchResults } from 'matrix-js-sdk/src/@types/search'; | ||||
| 
 | ||||
| import shouldHideEvent from '../../shouldHideEvent'; | ||||
| import { _t } from '../../languageHandler'; | ||||
|  | @ -133,12 +133,7 @@ export interface IState { | |||
|     searching: boolean; | ||||
|     searchTerm?: string; | ||||
|     searchScope?: SearchScope; | ||||
|     searchResults?: XOR<{}, { | ||||
|         count: number; | ||||
|         highlights: string[]; | ||||
|         results: SearchResult[]; | ||||
|         next_batch: string; // eslint-disable-line camelcase
 | ||||
|     }>; | ||||
|     searchResults?: XOR<{}, ISearchResults>; | ||||
|     searchHighlights?: string[]; | ||||
|     searchInProgress?: boolean; | ||||
|     callState?: CallState; | ||||
|  | @ -1137,7 +1132,7 @@ export default class RoomView extends React.Component<IProps, IState> { | |||
| 
 | ||||
|         if (this.state.searchResults.next_batch) { | ||||
|             debuglog("requesting more search results"); | ||||
|             const searchPromise = searchPagination(this.state.searchResults); | ||||
|             const searchPromise = searchPagination(this.state.searchResults as ISearchResults); | ||||
|             return this.handleSearchResult(searchPromise); | ||||
|         } else { | ||||
|             debuglog("no more search results"); | ||||
|  |  | |||
|  | @ -187,7 +187,7 @@ export default class ScrollPanel extends React.Component<IProps> { | |||
|     private fillRequestWhileRunning: boolean; | ||||
|     private scrollState: IScrollState; | ||||
|     private preventShrinkingState: IPreventShrinkingState; | ||||
|     private unfillDebouncer: NodeJS.Timeout; | ||||
|     private unfillDebouncer: number; | ||||
|     private bottomGrowth: number; | ||||
|     private pages: number; | ||||
|     private heightUpdateInProgress: boolean; | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ import React, { ReactNode, useMemo, useState } from "react"; | |||
| import { Room } from "matrix-js-sdk/src/models/room"; | ||||
| import { MatrixClient } from "matrix-js-sdk/src/client"; | ||||
| import { EventType, RoomType } from "matrix-js-sdk/src/@types/event"; | ||||
| import { ISpaceSummaryRoom, ISpaceSummaryEvent } from "matrix-js-sdk/src/@types/spaces"; | ||||
| import classNames from "classnames"; | ||||
| import { sortBy } from "lodash"; | ||||
| 
 | ||||
|  | @ -52,36 +53,6 @@ interface IHierarchyProps { | |||
|     showRoom(room: ISpaceSummaryRoom, viaServers?: string[], autoJoin?: boolean): void; | ||||
| } | ||||
| 
 | ||||
| /* eslint-disable camelcase */ | ||||
| export interface ISpaceSummaryRoom { | ||||
|     canonical_alias?: string; | ||||
|     aliases: string[]; | ||||
|     avatar_url?: string; | ||||
|     guest_can_join: boolean; | ||||
|     name?: string; | ||||
|     num_joined_members: number; | ||||
|     room_id: string; | ||||
|     topic?: string; | ||||
|     world_readable: boolean; | ||||
|     num_refs: number; | ||||
|     room_type: string; | ||||
| } | ||||
| 
 | ||||
| export interface ISpaceSummaryEvent { | ||||
|     room_id: string; | ||||
|     event_id: string; | ||||
|     origin_server_ts: number; | ||||
|     type: string; | ||||
|     state_key: string; | ||||
|     content: { | ||||
|         order?: string; | ||||
|         suggested?: boolean; | ||||
|         auto_join?: boolean; | ||||
|         via?: string[]; | ||||
|     }; | ||||
| } | ||||
| /* eslint-enable camelcase */ | ||||
| 
 | ||||
| interface ITileProps { | ||||
|     room: ISpaceSummaryRoom; | ||||
|     suggested?: boolean; | ||||
|  |  | |||
|  | @ -109,11 +109,11 @@ export abstract class Member { | |||
| 
 | ||||
| class DirectoryMember extends Member { | ||||
|     private readonly _userId: string; | ||||
|     private readonly displayName: string; | ||||
|     private readonly avatarUrl: string; | ||||
|     private readonly displayName?: string; | ||||
|     private readonly avatarUrl?: string; | ||||
| 
 | ||||
|     // eslint-disable-next-line camelcase
 | ||||
|     constructor(userDirResult: { user_id: string, display_name: string, avatar_url: string }) { | ||||
|     constructor(userDirResult: { user_id: string, display_name?: string, avatar_url?: string }) { | ||||
|         super(); | ||||
|         this._userId = userDirResult.user_id; | ||||
|         this.displayName = userDirResult.display_name; | ||||
|  | @ -370,7 +370,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps | |||
|     }; | ||||
| 
 | ||||
|     private closeCopiedTooltip: () => void; | ||||
|     private debounceTimer: NodeJS.Timeout = null; // actually number because we're in the browser
 | ||||
|     private debounceTimer: number = null; // actually number because we're in the browser
 | ||||
|     private editorRef = createRef<HTMLInputElement>(); | ||||
|     private unmounted = false; | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ limitations under the License. | |||
| 
 | ||||
| import React, { useEffect, useState } from "react"; | ||||
| import { MatrixError } from "matrix-js-sdk/src/http-api"; | ||||
| import { IProtocol } from "matrix-js-sdk/src/client"; | ||||
| 
 | ||||
| import { MatrixClientPeg } from '../../../MatrixClientPeg'; | ||||
| import { instanceForInstanceId } from '../../../utils/DirectoryUtils'; | ||||
|  | @ -83,30 +84,6 @@ const validServer = withValidation<undefined, { error?: MatrixError }>({ | |||
|     ], | ||||
| }); | ||||
| 
 | ||||
| /* eslint-disable camelcase */ | ||||
| export interface IFieldType { | ||||
|     regexp: string; | ||||
|     placeholder: string; | ||||
| } | ||||
| 
 | ||||
| export interface IInstance { | ||||
|     desc: string; | ||||
|     icon?: string; | ||||
|     fields: object; | ||||
|     network_id: string; | ||||
|     // XXX: this is undocumented but we rely on it.
 | ||||
|     instance_id: string; | ||||
| } | ||||
| 
 | ||||
| export interface IProtocol { | ||||
|     user_fields: string[]; | ||||
|     location_fields: string[]; | ||||
|     icon: string; | ||||
|     field_types: Record<string, IFieldType>; | ||||
|     instances: IInstance[]; | ||||
| } | ||||
| /* eslint-enable camelcase */ | ||||
| 
 | ||||
| export type Protocols = Record<string, IProtocol>; | ||||
| 
 | ||||
| interface IProps { | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ interface IProps { | |||
|     hasAvatar: boolean; | ||||
|     noAvatarLabel?: string; | ||||
|     hasAvatarLabel?: string; | ||||
|     setAvatarUrl(url: string): Promise<void>; | ||||
|     setAvatarUrl(url: string): Promise<unknown>; | ||||
| } | ||||
| 
 | ||||
| const MiniAvatarUploader: React.FC<IProps> = ({ hasAvatar, hasAvatarLabel, noAvatarLabel, setAvatarUrl, children }) => { | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ limitations under the License. | |||
| */ | ||||
| 
 | ||||
| import React from "react"; | ||||
| import { Visibility } from "matrix-js-sdk/src/@types/partials"; | ||||
| 
 | ||||
| import LabelledToggleSwitch from "../elements/LabelledToggleSwitch"; | ||||
| import { _t } from "../../../languageHandler"; | ||||
|  | @ -50,7 +51,7 @@ export default class RoomPublishSetting extends React.PureComponent<IProps, ISta | |||
| 
 | ||||
|         client.setRoomDirectoryVisibility( | ||||
|             this.props.roomId, | ||||
|             newValue ? 'public' : 'private', | ||||
|             newValue ? Visibility.Public : Visibility.Private, | ||||
|         ).catch(() => { | ||||
|             // Roll back the local echo on the change
 | ||||
|             this.setState({ isRoomPublished: valueBefore }); | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ interface IState { | |||
| export default class Autocomplete extends React.PureComponent<IProps, IState> { | ||||
|     autocompleter: Autocompleter; | ||||
|     queryRequested: string; | ||||
|     debounceCompletionsRequest: NodeJS.Timeout; | ||||
|     debounceCompletionsRequest: number; | ||||
|     private containerRef = createRef<HTMLDivElement>(); | ||||
| 
 | ||||
|     constructor(props) { | ||||
|  |  | |||
|  | @ -75,7 +75,7 @@ interface IState extends IThemeState { | |||
| export default class AppearanceUserSettingsTab extends React.Component<IProps, IState> { | ||||
|     private readonly MESSAGE_PREVIEW_TEXT = _t("Hey you. You're the best!"); | ||||
| 
 | ||||
|     private themeTimer: NodeJS.Timeout; | ||||
|     private themeTimer: number; | ||||
| 
 | ||||
|     constructor(props: IProps) { | ||||
|         super(props); | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ enum SpaceVisibility { | |||
| 
 | ||||
| const useLocalEcho = <T extends any>( | ||||
|     currentFactory: () => T, | ||||
|     setterFn: (value: T) => Promise<void>, | ||||
|     setterFn: (value: T) => Promise<unknown>, | ||||
|     errorFn: (error: Error) => void, | ||||
| ): [value: T, handler: (value: T) => void] => { | ||||
|     const [value, setValue] = useState(currentFactory); | ||||
|  |  | |||
|  | @ -44,7 +44,7 @@ interface IState { | |||
| 
 | ||||
| @replaceableComponent("views.toasts.VerificationRequestToast") | ||||
| export default class VerificationRequestToast extends React.PureComponent<IProps, IState> { | ||||
|     private intervalHandle: NodeJS.Timeout; | ||||
|     private intervalHandle: number; | ||||
| 
 | ||||
|     constructor(props) { | ||||
|         super(props); | ||||
|  |  | |||
|  | @ -14,47 +14,16 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| import { IMatrixProfile, IEventWithRoomId as IMatrixEvent, IResultRoomEvents } from "matrix-js-sdk/src/@types/search"; | ||||
| import { Direction } from "matrix-js-sdk/src"; | ||||
| 
 | ||||
| // The following interfaces take their names and member names from seshat and the spec
 | ||||
| /* eslint-disable camelcase */ | ||||
| 
 | ||||
| export interface IMatrixEvent { | ||||
|     type: string; | ||||
|     sender: string; | ||||
|     content: {}; | ||||
|     event_id: string; | ||||
|     origin_server_ts: number; | ||||
|     unsigned?: {}; | ||||
|     roomId: string; | ||||
| } | ||||
| 
 | ||||
| export interface IMatrixProfile { | ||||
|     avatar_url: string; | ||||
|     displayname: string; | ||||
| } | ||||
| 
 | ||||
| export interface ICrawlerCheckpoint { | ||||
|     roomId: string; | ||||
|     token: string; | ||||
|     fullCrawl?: boolean; | ||||
|     direction: string; | ||||
| } | ||||
| 
 | ||||
| export interface IResultContext { | ||||
|     events_before: [IMatrixEvent]; | ||||
|     events_after: [IMatrixEvent]; | ||||
|     profile_info: Map<string, IMatrixProfile>; | ||||
| } | ||||
| 
 | ||||
| export interface IResultsElement { | ||||
|     rank: number; | ||||
|     result: IMatrixEvent; | ||||
|     context: IResultContext; | ||||
| } | ||||
| 
 | ||||
| export interface ISearchResult { | ||||
|     count: number; | ||||
|     results: [IResultsElement]; | ||||
|     highlights: [string]; | ||||
|     direction: Direction; | ||||
| } | ||||
| 
 | ||||
| export interface ISearchArgs { | ||||
|  | @ -63,6 +32,8 @@ export interface ISearchArgs { | |||
|     after_limit: number; | ||||
|     order_by_recency: boolean; | ||||
|     room_id?: string; | ||||
|     limit: number; | ||||
|     next_batch?: string; | ||||
| } | ||||
| 
 | ||||
| export interface IEventAndProfile { | ||||
|  | @ -205,10 +176,10 @@ export default abstract class BaseEventIndexManager { | |||
|      * @param {ISearchArgs} searchArgs The search configuration for the search, | ||||
|      * sets the search term and determines the search result contents. | ||||
|      * | ||||
|      * @return {Promise<[ISearchResult]>} A promise that will resolve to an array | ||||
|      * @return {Promise<IResultRoomEvents[]>} A promise that will resolve to an array | ||||
|      * of search results once the search is done. | ||||
|      */ | ||||
|     async searchEventIndex(searchArgs: ISearchArgs): Promise<ISearchResult> { | ||||
|     async searchEventIndex(searchArgs: ISearchArgs): Promise<IResultRoomEvents> { | ||||
|         throw new Error("Unimplemented"); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ import { EventTimelineSet } from 'matrix-js-sdk/src/models/event-timeline-set'; | |||
| import { RoomState } from 'matrix-js-sdk/src/models/room-state'; | ||||
| import { TimelineWindow } from 'matrix-js-sdk/src/timeline-window'; | ||||
| import { sleep } from "matrix-js-sdk/src/utils"; | ||||
| import { IResultRoomEvents } from "matrix-js-sdk/src/@types/search"; | ||||
| 
 | ||||
| import PlatformPeg from "../PlatformPeg"; | ||||
| import { MatrixClientPeg } from "../MatrixClientPeg"; | ||||
|  | @ -114,14 +115,14 @@ export default class EventIndex extends EventEmitter { | |||
|             const backCheckpoint: ICrawlerCheckpoint = { | ||||
|                 roomId: room.roomId, | ||||
|                 token: token, | ||||
|                 direction: "b", | ||||
|                 direction: Direction.Backward, | ||||
|                 fullCrawl: true, | ||||
|             }; | ||||
| 
 | ||||
|             const forwardCheckpoint: ICrawlerCheckpoint = { | ||||
|                 roomId: room.roomId, | ||||
|                 token: token, | ||||
|                 direction: "f", | ||||
|                 direction: Direction.Forward, | ||||
|             }; | ||||
| 
 | ||||
|             try { | ||||
|  | @ -384,7 +385,7 @@ export default class EventIndex extends EventEmitter { | |||
|             roomId: room.roomId, | ||||
|             token: token, | ||||
|             fullCrawl: fullCrawl, | ||||
|             direction: "b", | ||||
|             direction: Direction.Backward, | ||||
|         }; | ||||
| 
 | ||||
|         console.log("EventIndex: Adding checkpoint", checkpoint); | ||||
|  | @ -671,10 +672,10 @@ export default class EventIndex extends EventEmitter { | |||
|      * @param {ISearchArgs} searchArgs The search configuration for the search, | ||||
|      * sets the search term and determines the search result contents. | ||||
|      * | ||||
|      * @return {Promise<[SearchResult]>} A promise that will resolve to an array | ||||
|      * @return {Promise<IResultRoomEvents[]>} A promise that will resolve to an array | ||||
|      * of search results once the search is done. | ||||
|      */ | ||||
|     public async search(searchArgs: ISearchArgs) { | ||||
|     public async search(searchArgs: ISearchArgs): Promise<IResultRoomEvents> { | ||||
|         const indexManager = PlatformPeg.get().getEventIndexingManager(); | ||||
|         return indexManager.searchEventIndex(searchArgs); | ||||
|     } | ||||
|  |  | |||
|  | @ -14,11 +14,13 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| import { IAbortablePromise } from "matrix-js-sdk/src/@types/partials"; | ||||
| 
 | ||||
| export interface IUpload { | ||||
|     fileName: string; | ||||
|     roomId: string; | ||||
|     total: number; | ||||
|     loaded: number; | ||||
|     promise: Promise<any>; | ||||
|     promise: IAbortablePromise<any>; | ||||
|     canceled?: boolean; | ||||
| } | ||||
|  |  | |||
|  | @ -123,12 +123,13 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa | |||
|         return preferredValue; | ||||
|     } | ||||
| 
 | ||||
|     public setValue(settingName: string, roomId: string, newValue: any): Promise<void> { | ||||
|     public async setValue(settingName: string, roomId: string, newValue: any): Promise<void> { | ||||
|         // Special case URL previews
 | ||||
|         if (settingName === "urlPreviewsEnabled") { | ||||
|             const content = this.getSettings("org.matrix.preview_urls") || {}; | ||||
|             content['disable'] = !newValue; | ||||
|             return MatrixClientPeg.get().setAccountData("org.matrix.preview_urls", content); | ||||
|             await MatrixClientPeg.get().setAccountData("org.matrix.preview_urls", content); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Special case for breadcrumbs
 | ||||
|  | @ -141,26 +142,29 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa | |||
|             if (!content) content = {}; // If we still don't have content, make some
 | ||||
| 
 | ||||
|             content['recent_rooms'] = newValue; | ||||
|             return MatrixClientPeg.get().setAccountData(BREADCRUMBS_EVENT_TYPE, content); | ||||
|             await MatrixClientPeg.get().setAccountData(BREADCRUMBS_EVENT_TYPE, content); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Special case recent emoji
 | ||||
|         if (settingName === "recent_emoji") { | ||||
|             const content = this.getSettings(RECENT_EMOJI_EVENT_TYPE) || {}; | ||||
|             content["recent_emoji"] = newValue; | ||||
|             return MatrixClientPeg.get().setAccountData(RECENT_EMOJI_EVENT_TYPE, content); | ||||
|             await MatrixClientPeg.get().setAccountData(RECENT_EMOJI_EVENT_TYPE, content); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Special case integration manager provisioning
 | ||||
|         if (settingName === "integrationProvisioning") { | ||||
|             const content = this.getSettings(INTEG_PROVISIONING_EVENT_TYPE) || {}; | ||||
|             content['enabled'] = newValue; | ||||
|             return MatrixClientPeg.get().setAccountData(INTEG_PROVISIONING_EVENT_TYPE, content); | ||||
|             await MatrixClientPeg.get().setAccountData(INTEG_PROVISIONING_EVENT_TYPE, content); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const content = this.getSettings() || {}; | ||||
|         content[settingName] = newValue; | ||||
|         return MatrixClientPeg.get().setAccountData("im.vector.web.settings", content); | ||||
|         await MatrixClientPeg.get().setAccountData("im.vector.web.settings", content); | ||||
|     } | ||||
| 
 | ||||
|     public canSetValue(settingName: string, roomId: string): boolean { | ||||
|  |  | |||
|  | @ -86,22 +86,24 @@ export default class RoomAccountSettingsHandler extends MatrixClientBackedSettin | |||
|         return settings[settingName]; | ||||
|     } | ||||
| 
 | ||||
|     public setValue(settingName: string, roomId: string, newValue: any): Promise<void> { | ||||
|     public async setValue(settingName: string, roomId: string, newValue: any): Promise<void> { | ||||
|         // Special case URL previews
 | ||||
|         if (settingName === "urlPreviewsEnabled") { | ||||
|             const content = this.getSettings(roomId, "org.matrix.room.preview_urls") || {}; | ||||
|             content['disable'] = !newValue; | ||||
|             return MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.preview_urls", content); | ||||
|             await MatrixClientPeg.get().setRoomAccountData(roomId, "org.matrix.room.preview_urls", content); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Special case allowed widgets
 | ||||
|         if (settingName === "allowedWidgets") { | ||||
|             return MatrixClientPeg.get().setRoomAccountData(roomId, ALLOWED_WIDGETS_EVENT_TYPE, newValue); | ||||
|             await MatrixClientPeg.get().setRoomAccountData(roomId, ALLOWED_WIDGETS_EVENT_TYPE, newValue); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const content = this.getSettings(roomId) || {}; | ||||
|         content[settingName] = newValue; | ||||
|         return MatrixClientPeg.get().setRoomAccountData(roomId, "im.vector.web.settings", content); | ||||
|         await MatrixClientPeg.get().setRoomAccountData(roomId, "im.vector.web.settings", content); | ||||
|     } | ||||
| 
 | ||||
|     public canSetValue(settingName: string, roomId: string): boolean { | ||||
|  |  | |||
|  | @ -87,17 +87,18 @@ export default class RoomSettingsHandler extends MatrixClientBackedSettingsHandl | |||
|         return settings[settingName]; | ||||
|     } | ||||
| 
 | ||||
|     public setValue(settingName: string, roomId: string, newValue: any): Promise<void> { | ||||
|     public async setValue(settingName: string, roomId: string, newValue: any): Promise<void> { | ||||
|         // Special case URL previews
 | ||||
|         if (settingName === "urlPreviewsEnabled") { | ||||
|             const content = this.getSettings(roomId, "org.matrix.room.preview_urls") || {}; | ||||
|             content['disable'] = !newValue; | ||||
|             return MatrixClientPeg.get().sendStateEvent(roomId, "org.matrix.room.preview_urls", content); | ||||
|             await MatrixClientPeg.get().sendStateEvent(roomId, "org.matrix.room.preview_urls", content); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const content = this.getSettings(roomId) || {}; | ||||
|         content[settingName] = newValue; | ||||
|         return MatrixClientPeg.get().sendStateEvent(roomId, "im.vector.web.settings", content, ""); | ||||
|         await MatrixClientPeg.get().sendStateEvent(roomId, "im.vector.web.settings", content, ""); | ||||
|     } | ||||
| 
 | ||||
|     public canSetValue(settingName: string, roomId: string): boolean { | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ import { ListIteratee, Many, sortBy, throttle } from "lodash"; | |||
| import { EventType, RoomType } from "matrix-js-sdk/src/@types/event"; | ||||
| import { Room } from "matrix-js-sdk/src/models/room"; | ||||
| import { MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||||
| import { ISpaceSummaryRoom } from "matrix-js-sdk/src/@types/spaces"; | ||||
| 
 | ||||
| import { AsyncStoreWithClient } from "./AsyncStoreWithClient"; | ||||
| import defaultDispatcher from "../dispatcher/dispatcher"; | ||||
|  | @ -31,7 +32,6 @@ import { RoomNotificationStateStore } from "./notifications/RoomNotificationStat | |||
| import { DefaultTagID } from "./room-list/models"; | ||||
| import { EnhancedMap, mapDiff } from "../utils/maps"; | ||||
| import { setHasDiff } from "../utils/sets"; | ||||
| import { ISpaceSummaryEvent, ISpaceSummaryRoom } from "../components/structures/SpaceRoomDirectory"; | ||||
| import RoomViewStore from "./RoomViewStore"; | ||||
| import { Action } from "../dispatcher/actions"; | ||||
| import { arrayHasDiff } from "../utils/arrays"; | ||||
|  | @ -184,10 +184,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> { | |||
| 
 | ||||
|     public fetchSuggestedRooms = async (space: Room, limit = MAX_SUGGESTED_ROOMS): Promise<ISuggestedRoom[]> => { | ||||
|         try { | ||||
|             const data: { | ||||
|                 rooms: ISpaceSummaryRoom[]; | ||||
|                 events: ISpaceSummaryEvent[]; | ||||
|             } = await this.matrixClient.getSpaceSummary(space.roomId, 0, true, false, limit); | ||||
|             const data = await this.matrixClient.getSpaceSummary(space.roomId, 0, true, false, limit); | ||||
| 
 | ||||
|             const viaMap = new EnhancedMap<string, Set<string>>(); | ||||
|             data.events.forEach(ev => { | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ Once a timer is finished or aborted, it can't be started again | |||
| a new one through `clone()` or `cloneIfRun()`. | ||||
| */ | ||||
| export default class Timer { | ||||
|     private timerHandle: NodeJS.Timeout; | ||||
|     private timerHandle: number; | ||||
|     private startTs: number; | ||||
|     private promise: Promise<void>; | ||||
|     private resolve: () => void; | ||||
|  |  | |||
|  | @ -386,7 +386,7 @@ export default class WidgetUtils { | |||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     static removeIntegrationManagerWidgets(): Promise<void> { | ||||
|     static async removeIntegrationManagerWidgets(): Promise<void> { | ||||
|         const client = MatrixClientPeg.get(); | ||||
|         if (!client) { | ||||
|             throw new Error('User not logged in'); | ||||
|  | @ -399,7 +399,7 @@ export default class WidgetUtils { | |||
|                 delete userWidgets[key]; | ||||
|             } | ||||
|         }); | ||||
|         return client.setAccountData('m.widgets', userWidgets); | ||||
|         await client.setAccountData('m.widgets', userWidgets); | ||||
|     } | ||||
| 
 | ||||
|     static addIntegrationManagerWidget(name: string, uiUrl: string, apiUrl: string): Promise<void> { | ||||
|  | @ -416,7 +416,7 @@ export default class WidgetUtils { | |||
|      * Remove all stickerpicker widgets (stickerpickers are user widgets by nature) | ||||
|      * @return {Promise} Resolves on account data updated | ||||
|      */ | ||||
|     static removeStickerpickerWidgets(): Promise<void> { | ||||
|     static async removeStickerpickerWidgets(): Promise<void> { | ||||
|         const client = MatrixClientPeg.get(); | ||||
|         if (!client) { | ||||
|             throw new Error('User not logged in'); | ||||
|  | @ -429,7 +429,7 @@ export default class WidgetUtils { | |||
|                 delete userWidgets[key]; | ||||
|             } | ||||
|         }); | ||||
|         return client.setAccountData('m.widgets', userWidgets); | ||||
|         await client.setAccountData('m.widgets', userWidgets); | ||||
|     } | ||||
| 
 | ||||
|     static makeAppConfig( | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ import Modal from './Modal'; | |||
| import { RightPanelPhases } from "./stores/RightPanelStorePhases"; | ||||
| import { findDMForUser } from './createRoom'; | ||||
| import { accessSecretStorage } from './SecurityManager'; | ||||
| import { verificationMethods } from 'matrix-js-sdk/src/crypto'; | ||||
| import { verificationMethods as VerificationMethods } from 'matrix-js-sdk/src/crypto'; | ||||
| import { Action } from './dispatcher/actions'; | ||||
| import UntrustedDeviceDialog from "./components/views/dialogs/UntrustedDeviceDialog"; | ||||
| import { IDevice } from "./components/views/right_panel/UserInfo"; | ||||
|  | @ -63,7 +63,7 @@ export async function verifyDevice(user: User, device: IDevice) { | |||
|                 const verificationRequestPromise = cli.legacyDeviceVerification( | ||||
|                     user.userId, | ||||
|                     device.deviceId, | ||||
|                     verificationMethods.SAS, | ||||
|                     VerificationMethods.SAS, | ||||
|                 ); | ||||
|                 dis.dispatch({ | ||||
|                     action: Action.SetRightPanelPhase, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Michael Telatynski
						Michael Telatynski