Modernize Benchmarks CI
This commit is contained in:
77
ts/CI.ts
Normal file
77
ts/CI.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { ipcRenderer } from 'electron';
|
||||
|
||||
import { explodePromise } from './util/explodePromise';
|
||||
|
||||
type ResolveType = (data: unknown) => void;
|
||||
|
||||
export const electronRequire = require;
|
||||
|
||||
export class CI {
|
||||
private readonly eventListeners = new Map<string, Array<ResolveType>>();
|
||||
|
||||
private readonly completedEvents = new Map<string, Array<unknown>>();
|
||||
|
||||
constructor(public readonly deviceName: string) {
|
||||
ipcRenderer.on('ci:event', (_, event, data) => {
|
||||
this.handleEvent(event, data);
|
||||
});
|
||||
}
|
||||
|
||||
public async waitForEvent(event: string): Promise<unknown> {
|
||||
const pendingCompleted = this.completedEvents.get(event) || [];
|
||||
const pending = pendingCompleted.shift();
|
||||
if (pending) {
|
||||
window.log.info(`CI: resolving pending result for ${event}`, pending);
|
||||
|
||||
if (pendingCompleted.length === 0) {
|
||||
this.completedEvents.delete(event);
|
||||
}
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
window.log.info(`CI: waiting for event ${event}`);
|
||||
const { resolve, promise } = explodePromise();
|
||||
|
||||
let list = this.eventListeners.get(event);
|
||||
if (!list) {
|
||||
list = [];
|
||||
this.eventListeners.set(event, list);
|
||||
}
|
||||
|
||||
list.push(resolve);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
public setProvisioningURL(url: string): void {
|
||||
this.handleEvent('provisioning-url', url);
|
||||
}
|
||||
|
||||
public handleEvent(event: string, data: unknown): void {
|
||||
const list = this.eventListeners.get(event) || [];
|
||||
const resolve = list.shift();
|
||||
|
||||
if (resolve) {
|
||||
if (list.length === 0) {
|
||||
this.eventListeners.delete(event);
|
||||
}
|
||||
|
||||
window.log.info(`CI: got event ${event} with data`, data);
|
||||
resolve(data);
|
||||
return;
|
||||
}
|
||||
|
||||
window.log.info(`CI: postponing event ${event}`);
|
||||
|
||||
let resultList = this.completedEvents.get(event);
|
||||
if (!resultList) {
|
||||
resultList = [];
|
||||
this.completedEvents.set(event, resultList);
|
||||
}
|
||||
resultList.push(data);
|
||||
}
|
||||
}
|
@@ -86,7 +86,7 @@ export type Props = {
|
||||
const MAX_LENGTH = 64 * 1024;
|
||||
const BASE_CLASS_NAME = 'module-composition-input';
|
||||
|
||||
export const CompositionInput: React.ComponentType<Props> = props => {
|
||||
export function CompositionInput(props: Props): React.ReactElement {
|
||||
const {
|
||||
i18n,
|
||||
disabled,
|
||||
@@ -644,4 +644,4 @@ export const CompositionInput: React.ComponentType<Props> = props => {
|
||||
</Reference>
|
||||
</Manager>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
@@ -478,6 +478,10 @@ export class Message extends React.PureComponent<Props, State> {
|
||||
status === 'viewed')
|
||||
) {
|
||||
const delta = Date.now() - timestamp;
|
||||
window.CI?.handleEvent('message:send-complete', {
|
||||
timestamp,
|
||||
delta,
|
||||
});
|
||||
window.log.info(
|
||||
`Message.tsx: Rendered 'send complete' for message ${timestamp}; took ${delta}ms`
|
||||
);
|
||||
|
@@ -54,7 +54,7 @@ type PropsType = {
|
||||
>;
|
||||
|
||||
export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo(
|
||||
({
|
||||
function BaseConversationListItem({
|
||||
acceptedMessageRequest,
|
||||
avatarPath,
|
||||
checked,
|
||||
@@ -79,7 +79,7 @@ export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo
|
||||
title,
|
||||
unblurredAvatarPath,
|
||||
unreadCount,
|
||||
}) => {
|
||||
}) {
|
||||
const isUnread = isConversationUnread({ markedUnread, unreadCount });
|
||||
|
||||
const isAvatarNoteToSelf = isBoolean(isNoteToSelf)
|
||||
|
@@ -47,7 +47,7 @@ type PropsHousekeepingType = {
|
||||
type PropsType = PropsDataType & PropsHousekeepingType;
|
||||
|
||||
export const ContactCheckbox: FunctionComponent<PropsType> = React.memo(
|
||||
({
|
||||
function ContactCheckbox({
|
||||
about,
|
||||
acceptedMessageRequest,
|
||||
avatarPath,
|
||||
@@ -65,7 +65,7 @@ export const ContactCheckbox: FunctionComponent<PropsType> = React.memo(
|
||||
title,
|
||||
type,
|
||||
unblurredAvatarPath,
|
||||
}) => {
|
||||
}) {
|
||||
const disabled = Boolean(disabledReason);
|
||||
|
||||
const headerName = isMe ? (
|
||||
|
@@ -34,7 +34,7 @@ type PropsHousekeepingType = {
|
||||
type PropsType = PropsDataType & PropsHousekeepingType;
|
||||
|
||||
export const ContactListItem: FunctionComponent<PropsType> = React.memo(
|
||||
({
|
||||
function ContactListItem({
|
||||
about,
|
||||
acceptedMessageRequest,
|
||||
avatarPath,
|
||||
@@ -50,7 +50,7 @@ export const ContactListItem: FunctionComponent<PropsType> = React.memo(
|
||||
title,
|
||||
type,
|
||||
unblurredAvatarPath,
|
||||
}) => {
|
||||
}) {
|
||||
const headerName = isMe ? (
|
||||
i18n('noteToSelf')
|
||||
) : (
|
||||
|
@@ -63,7 +63,7 @@ type PropsHousekeeping = {
|
||||
export type Props = PropsData & PropsHousekeeping;
|
||||
|
||||
export const ConversationListItem: FunctionComponent<Props> = React.memo(
|
||||
({
|
||||
function ConversationListItem({
|
||||
acceptedMessageRequest,
|
||||
avatarPath,
|
||||
color,
|
||||
@@ -87,7 +87,7 @@ export const ConversationListItem: FunctionComponent<Props> = React.memo(
|
||||
typingContact,
|
||||
unblurredAvatarPath,
|
||||
unreadCount,
|
||||
}) => {
|
||||
}) {
|
||||
const headerName = isMe ? (
|
||||
i18n('noteToSelf')
|
||||
) : (
|
||||
|
@@ -12,7 +12,7 @@ type PropsType = {
|
||||
};
|
||||
|
||||
export const CreateNewGroupButton: FunctionComponent<PropsType> = React.memo(
|
||||
({ i18n, onClick }) => {
|
||||
function CreateNewGroupButton({ i18n, onClick }) {
|
||||
const title = i18n('createNewGroupButton');
|
||||
|
||||
return (
|
||||
|
@@ -143,7 +143,7 @@ function getFilteredBodyRanges(
|
||||
}
|
||||
|
||||
export const MessageSearchResult: FunctionComponent<PropsType> = React.memo(
|
||||
({
|
||||
function MessageSearchResult({
|
||||
body,
|
||||
bodyRanges,
|
||||
conversationId,
|
||||
@@ -154,7 +154,7 @@ export const MessageSearchResult: FunctionComponent<PropsType> = React.memo(
|
||||
sentAt,
|
||||
snippet,
|
||||
to,
|
||||
}) => {
|
||||
}) {
|
||||
const onClickItem = useCallback(() => {
|
||||
openConversationInternal({ conversationId, messageId: id });
|
||||
}, [openConversationInternal, conversationId, id]);
|
||||
|
@@ -25,7 +25,7 @@ type PropsHousekeeping = {
|
||||
export type Props = PropsData & PropsHousekeeping;
|
||||
|
||||
export const StartNewConversation: FunctionComponent<Props> = React.memo(
|
||||
({ i18n, onClick, phoneNumber }) => {
|
||||
function StartNewConversation({ i18n, onClick, phoneNumber }) {
|
||||
const messageText = (
|
||||
<div className={TEXT_CLASS_NAME}>{i18n('startConversation')}</div>
|
||||
);
|
||||
|
@@ -222,9 +222,7 @@ export default class AccountManager extends EventTarget {
|
||||
}
|
||||
const url = getProvisioningUrl(uuid, pubKey);
|
||||
|
||||
if (window.CI) {
|
||||
window.CI.setProvisioningURL(url);
|
||||
}
|
||||
window.CI?.setProvisioningURL(url);
|
||||
|
||||
setProvisioningUrl(url);
|
||||
request.respond(200, 'OK');
|
||||
|
8
ts/window.d.ts
vendored
8
ts/window.d.ts
vendored
@@ -117,6 +117,7 @@ import { MessageController } from './util/MessageController';
|
||||
import { isValidGuid } from './util/isValidGuid';
|
||||
import { StateType } from './state/reducer';
|
||||
import { SystemTraySetting } from './types/SystemTraySetting';
|
||||
import { CI } from './CI';
|
||||
|
||||
export { Long } from 'long';
|
||||
|
||||
@@ -277,12 +278,7 @@ declare global {
|
||||
};
|
||||
|
||||
Backbone: typeof Backbone;
|
||||
CI:
|
||||
| {
|
||||
setProvisioningURL: (url: string) => void;
|
||||
deviceName: string;
|
||||
}
|
||||
| undefined;
|
||||
CI?: CI;
|
||||
Accessibility: {
|
||||
reducedMotionSetting: boolean;
|
||||
};
|
||||
|
Reference in New Issue
Block a user