Merge branch 'watcha-feature/bump-matrix-js-sdk-from-19.0.0-to-19.1.0' into watcha-develop

watcha-develop watcha-20230215T151825-cfdc4c6-21d26a1-e69d85a
c-cal 3 years ago
commit e69d85a306
Signed by: watcha
GPG Key ID: 87DD78E7F7A1581D
  1. 119
      src/client.ts
  2. 7
      src/http-api.ts
  3. 9
      src/models/room-state.ts
  4. 34
      src/models/room.ts

@ -64,6 +64,7 @@ import {
PREFIX_V3, PREFIX_V3,
retryNetworkOperation, retryNetworkOperation,
UploadContentResponseType, UploadContentResponseType,
PREFIX_WATCHA_NEXTCLOUD, // watcha+
} from "./http-api"; } from "./http-api";
import { import {
Crypto, Crypto,
@ -202,6 +203,7 @@ const SCROLLBACK_DELAY_MS = 3000;
export const CRYPTO_ENABLED: boolean = isCryptoAvailable(); export const CRYPTO_ENABLED: boolean = isCryptoAvailable();
const CAPABILITIES_CACHE_MS = 21600000; // 6 hours - an arbitrary value const CAPABILITIES_CACHE_MS = 21600000; // 6 hours - an arbitrary value
const TURN_CHECK_INTERVAL = 10 * 60 * 1000; // poll for turn credentials every 10 minutes const TURN_CHECK_INTERVAL = 10 * 60 * 1000; // poll for turn credentials every 10 minutes
const CALENDAR_EVENT_TYPE = "watcha.room.nextcloud_calendar"; // watcha+
interface IExportedDevice { interface IExportedDevice {
olmDevice: IOlmDevice; olmDevice: IOlmDevice;
@ -763,6 +765,26 @@ interface ITimestampToEventResponse {
event_id: string; event_id: string;
origin_server_ts: string; origin_server_ts: string;
} }
// watcha+
export interface IOwnCalendars {
VEVENT_VTODO: IOwnCalendar[];
VEVENT: IOwnCalendar[];
VTODO: IOwnCalendar[];
}
export interface IOwnCalendar {
id: number;
displayname: string;
}
export interface ICalendar {
id: number;
displayname: string;
components: string[];
is_personal: boolean;
}
// +watcha
/* eslint-enable camelcase */ /* eslint-enable camelcase */
// We're using this constant for methods overloading and inspect whether a variable // We're using this constant for methods overloading and inspect whether a variable
@ -897,6 +919,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
protected canSupportVoip = false; protected canSupportVoip = false;
protected peekSync: SyncApi = null; protected peekSync: SyncApi = null;
protected isGuestAccount = false; protected isGuestAccount = false;
protected isPartnerAccount = false; // watcha+
protected ongoingScrollbacks: {[roomId: string]: {promise?: Promise<Room>, errorTs?: number}} = {}; protected ongoingScrollbacks: {[roomId: string]: {promise?: Promise<Room>, errorTs?: number}} = {};
protected notifTimelineSet: EventTimelineSet = null; protected notifTimelineSet: EventTimelineSet = null;
protected cryptoStore: CryptoStore; protected cryptoStore: CryptoStore;
@ -1539,6 +1562,24 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
this.isGuestAccount = guest; this.isGuestAccount = guest;
} }
// watcha+
/**
* Return whether the client is configured for a partner account.
* @return {boolean} True if this is a partner account.
*/
public isPartner(): boolean {
return this.isPartnerAccount;
}
/**
* Set whether this client is a partner account.
* @param {boolean} partner True if this is a partner account.
*/
public setPartner(partner: boolean) {
this.isPartnerAccount = partner;
}
// +watcha
/** /**
* Return the provided scheduler, if any. * Return the provided scheduler, if any.
* @return {?module:scheduler~MatrixScheduler} The scheduler or null * @return {?module:scheduler~MatrixScheduler} The scheduler or null
@ -4795,7 +4836,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
{ $roomId: roomId }, { $roomId: roomId },
); );
/* watcha!
const identityServerUrl = this.getIdentityServerUrl(true); const identityServerUrl = this.getIdentityServerUrl(true);
!watcha */
const identityServerUrl = "fake-is.watcha.fr"; // watcha+ until we have an IS
if (!identityServerUrl) { if (!identityServerUrl) {
return Promise.reject(new MatrixError({ return Promise.reject(new MatrixError({
error: "No supplied identity server URL", error: "No supplied identity server URL",
@ -6402,7 +6446,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
private async fetchClientWellKnown(): Promise<void> { private async fetchClientWellKnown(): Promise<void> {
// `getRawClientConfig` does not throw or reject on network errors, instead // `getRawClientConfig` does not throw or reject on network errors, instead
// it absorbs errors and returns `{}`. // it absorbs errors and returns `{}`.
/* watcha!
this.clientWellKnownPromise = AutoDiscovery.getRawClientConfig(this.getDomain()); this.clientWellKnownPromise = AutoDiscovery.getRawClientConfig(this.getDomain());
!watcha */
this.clientWellKnownPromise = AutoDiscovery.getRawClientConfig(window.location.hostname); // watcha+
this.clientWellKnown = await this.clientWellKnownPromise; this.clientWellKnown = await this.clientWellKnownPromise;
this.emit(ClientEvent.ClientWellKnown, this.clientWellKnown); this.emit(ClientEvent.ClientWellKnown, this.clientWellKnown);
} }
@ -7744,7 +7791,11 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
info?: string, info?: string,
callback?: Callback, callback?: Callback,
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
/* watcha!
): Promise<{ avatar_url?: string, displayname?: string }> { ): Promise<{ avatar_url?: string, displayname?: string }> {
!watcha */
/* eslint-disable-next-line camelcase */// watcha+
): Promise<{ avatar_url?: string, displayname?: string, email: string }> { // watcha+ until we have an IS
if (utils.isFunction(info)) { if (utils.isFunction(info)) {
callback = info as any as Callback; // legacy callback = info as any as Callback; // legacy
info = undefined; info = undefined;
@ -8908,6 +8959,74 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
return new MSC3089TreeSpace(this, roomId); return new MSC3089TreeSpace(this, roomId);
} }
// watcha+
/**
* @return {Promise<IOwnCalendars>}
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
public getOwnCalendars(): Promise<IOwnCalendars> {
return this.http.authedRequest(undefined, Method.Get, "/calendars", undefined, undefined, {
prefix: PREFIX_WATCHA_NEXTCLOUD,
});
}
/**
* @param {number} calendarId
* @return {Promise<ICalendar>}
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
public getCalendar(calendarId: number): Promise<ICalendar> {
const path = utils.encodeUri("/calendars/$calendarId", {
$calendarId: calendarId.toString(),
});
return this.http.authedRequest(undefined, Method.Get, path, undefined, undefined, {
prefix: PREFIX_WATCHA_NEXTCLOUD,
});
}
/**
* @param {number} calendarId
* @return {Promise<{}>}
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
public reorderCalendars(calendarId: string): Promise<{}> {
const path = utils.encodeUri("/calendars/$calendarId/top", {
$calendarId: calendarId.toString(),
});
return this.http.authedRequest(undefined, Method.Put, path, undefined, undefined, {
prefix: PREFIX_WATCHA_NEXTCLOUD,
});
}
/**
* @param {string} roomId
* @param {number} calendarId Optional.
* @return {Promise<ISendEventResponse>}
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
public async setRoomCalendar(
roomId: string,
calendarId: number = null,
): Promise<ISendEventResponse> {
return this.sendStateEvent(roomId, CALENDAR_EVENT_TYPE, {
id: calendarId,
});
}
/**
* @param {string} roomId
* @param {string} stateKey
* @return {Promise<ISendEventResponse>}
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
public async unsetRoomCalendar(
roomId: string,
stateKey: string,
): Promise<ISendEventResponse> {
return this.sendStateEvent(roomId, CALENDAR_EVENT_TYPE, {}, stateKey);
}
// +watcha
/** /**
* @experimental * @experimental
*/ */

@ -78,6 +78,13 @@ export const PREFIX_IDENTITY_V2 = "/_matrix/identity/v2";
*/ */
export const PREFIX_MEDIA_R0 = "/_matrix/media/r0"; export const PREFIX_MEDIA_R0 = "/_matrix/media/r0";
// watcha+
/**
* URI path for the Nextcloud integration API
*/
export const PREFIX_WATCHA_NEXTCLOUD = "/_watcha/nextcloud";
// +watcha
type RequestProps = "method" type RequestProps = "method"
| "withCredentials" | "withCredentials"
| "json" | "json"

@ -793,6 +793,15 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
if (cli.isGuest()) { if (cli.isGuest()) {
return false; return false;
} }
// watcha+
if (cli.isPartner() && [
EventType.RoomTombstone,
EventType.SpaceChild,
EventType.SpaceParent,
].includes(stateEventType as EventType)) {
return false;
}
// +watcha
return this.maySendStateEvent(stateEventType, cli.credentials.userId); return this.maySendStateEvent(stateEventType, cli.credentials.userId);
} }

@ -2765,6 +2765,7 @@ export class Room extends TypedEventEmitter<EmittedEvents, RoomEventHandlerMap>
* @returns {boolean} true if the user should be permitted to issue invites for this room. * @returns {boolean} true if the user should be permitted to issue invites for this room.
*/ */
public canInvite(userId: string): boolean { public canInvite(userId: string): boolean {
if (this.client.isPartner()) return false; // watcha+
let canInvite = this.getMyMembership() === "join"; let canInvite = this.getMyMembership() === "join";
const powerLevelsEvent = this.currentState.getStateEvents(EventType.RoomPowerLevels, ""); const powerLevelsEvent = this.currentState.getStateEvents(EventType.RoomPowerLevels, "");
const powerLevels = powerLevelsEvent && powerLevelsEvent.getContent(); const powerLevels = powerLevelsEvent && powerLevelsEvent.getContent();
@ -2849,6 +2850,8 @@ export class Room extends TypedEventEmitter<EmittedEvents, RoomEventHandlerMap>
* @return {string} The calculated room name. * @return {string} The calculated room name.
*/ */
private calculateRoomName(userId: string, ignoreRoomNameEvent = false): string { private calculateRoomName(userId: string, ignoreRoomNameEvent = false): string {
const mxLocalSettings = JSON.parse(localStorage.getItem('mx_local_settings')); // watcha+ until https://github.com/matrix-org/matrix-js-sdk/issues/1309
const isCurrentLangFr = mxLocalSettings?.language === "fr"; // watcha+
if (!ignoreRoomNameEvent) { if (!ignoreRoomNameEvent) {
// check for an alias, if any. for now, assume first alias is the // check for an alias, if any. for now, assume first alias is the
// official one. // official one.
@ -2926,6 +2929,13 @@ export class Room extends TypedEventEmitter<EmittedEvents, RoomEventHandlerMap>
return i.getContent().display_name; return i.getContent().display_name;
}); });
// watcha+
if (isCurrentLangFr) {
return thirdPartyNames.length === 1
? `Invitation envoyée (${memberNamesToRoomName(thirdPartyNames)})`
: `Invitations envoyées (${memberNamesToRoomName(thirdPartyNames)})`;
}
// +watcha
return `Inviting ${memberNamesToRoomName(thirdPartyNames)}`; return `Inviting ${memberNamesToRoomName(thirdPartyNames)}`;
} }
} }
@ -2940,8 +2950,10 @@ export class Room extends TypedEventEmitter<EmittedEvents, RoomEventHandlerMap>
}).map((m) => m.name); }).map((m) => m.name);
} }
if (leftNames.length) { if (leftNames.length) {
if (isCurrentLangFr) return `Salon vide (auparavant ${memberNamesToRoomName(leftNames)})`; // watcha+
return `Empty room (was ${memberNamesToRoomName(leftNames)})`; return `Empty room (was ${memberNamesToRoomName(leftNames)})`;
} else { } else {
if (isCurrentLangFr) return "Salon vide"; // watcha+
return "Empty room"; return "Empty room";
} }
} }
@ -3130,6 +3142,8 @@ const ALLOWED_TRANSITIONS: Record<EventStatus, EventStatus[]> = {
// TODO i18n // TODO i18n
function memberNamesToRoomName(names: string[], count = (names.length + 1)) { function memberNamesToRoomName(names: string[], count = (names.length + 1)) {
const mxLocalSettings = JSON.parse(localStorage.getItem('mx_local_settings')); // watcha+
if (mxLocalSettings?.language === "fr") return memberNamesToRoomNameFr(names, count); // watcha+
const countWithoutMe = count - 1; const countWithoutMe = count - 1;
if (!names.length) { if (!names.length) {
return "Empty room"; return "Empty room";
@ -3147,6 +3161,26 @@ function memberNamesToRoomName(names: string[], count = (names.length + 1)) {
} }
} }
// watcha+
function memberNamesToRoomNameFr(names, count = (names.length + 1)) {
const countWithoutMe = count - 1;
if (!names.length) {
return "Salon vide";
} else if (names.length === 1 && countWithoutMe <= 1) {
return names[0];
} else if (names.length === 2 && countWithoutMe <= 2) {
return `${names[0]} et ${names[1]}`;
} else {
const plural = countWithoutMe > 1;
if (plural) {
return `${names[0]} et ${countWithoutMe} autres`;
} else {
return `${names[0]} et 1 autre`;
}
}
}
// +watcha
/** /**
* Fires when an event we had previously received is redacted. * Fires when an event we had previously received is redacted.
* *

Loading…
Cancel
Save