Added SessionToggle, SessionModal, and SessionDropdown comp… (#710)

Added SessionToggle, SessionModal, and SessionDropdown components
pull/737/head
Audric Ackermann 5 years ago committed by GitHub
commit 687b4d09da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1133,7 +1133,7 @@
"Confirmation dialog text that asks the user if they really wish to delete the conversation. Answer buttons use the strings 'ok' and 'cancel'. The deletion is permanent, i.e. it cannot be undone."
},
"deletePublicChannel": {
"message": "Leave public channel",
"message": "Leave Channel",
"description":
"Confirmation dialog title that asks the user if they really wish to delete a public channel. Answer buttons use the strings 'ok' and 'cancel'. The deletion is permanent, i.e. it cannot be undone."
},
@ -1817,7 +1817,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start new conversation…",
"message": "Start New Conversation",
"description":
"Label underneath number a user enters that is not an existing contact"
},
@ -2259,6 +2259,12 @@
"editProfileDialogTitle": {
"message": "Editing Profile"
},
"editProfileModalTitle": {
"message": "Edit Profile",
"description": "Title for the Edit Profile modal"
},
"profileName": {
"message": "Profile Name"
},

@ -701,6 +701,9 @@
<script type='text/javascript' src='js/views/scroll_down_button_view.js'></script>
<script type='text/javascript' src='js/views/toast_view.js'></script>
<script type='text/javascript' src='js/views/session_toast_view.js'></script>
<script type='text/javascript' src='js/views/session_toggle_view.js'></script>
<script type='text/javascript' src='js/views/session_modal_view.js'></script>
<script type='text/javascript' src='js/views/session_dropdown_view.js'></script>
<script type='text/javascript' src='js/views/file_input_view.js'></script>
<script type='text/javascript' src='js/views/list_view.js'></script>
<script type='text/javascript' src='js/views/contact_list_view.js'></script>

@ -802,6 +802,18 @@
appView.openConversation(groupId, {});
};
// $(document).ready(() => {
// window.settingsView = new Whisper.SessionSettingsView({
// el: $('#settings-container'),
// });
// window.settingsView.render();
// });
window.generateID = () =>
Math.random()
.toString(36)
.substring(3);
window.toasts = new Map();
window.pushToast = options => {
// Setting toasts with the same ID can be used to prevent identical
@ -810,22 +822,19 @@
const params = {
title: options.title,
id:
options.id ||
Math.random()
.toString(36)
.substring(3),
id: options.id || window.generateID(),
description: options.description || '',
type: options.type || '',
};
// Give all toasts an ID. User may define.
let currentToast;
const toastID = params.id;
const toast = !!toastID && window.toasts.get(toastID);
if (toast) {
window.toasts.get(toastID).update(params);
currentToast = window.toasts.get(toastID);
currentToast.update(params);
} else {
// Make new Toast
window.toasts.set(
toastID,
@ -834,8 +843,9 @@
})
);
window.toasts.get(toastID).render();
window.toasts.get(toastID).update(params);
currentToast = window.toasts.get(toastID);
currentToast.render();
currentToast.update(params);
}
// Remove some toasts if too many exist

@ -50,7 +50,15 @@ const {
} = require('../../ts/components/conversation/CreateGroupDialog');
const { EditProfileDialog } = require('../../ts/components/EditProfileDialog');
const { UserDetailsDialog } = require('../../ts/components/UserDetailsDialog');
const {
SessionSettings,
} = require('../../ts/components/session/SessionSettings');
const { SessionToast } = require('../../ts/components/session/SessionToast');
const { SessionToggle } = require('../../ts/components/session/SessionToggle');
const { SessionModal } = require('../../ts/components/session/SessionModal');
const {
SessionDropdown,
} = require('../../ts/components/session/SessionDropdown');
const {
SessionRegistrationView,
} = require('../../ts/components/session/SessionRegistrationView');
@ -249,7 +257,11 @@ exports.setup = (options = {}) => {
InviteFriendsDialog,
GroupInvitation,
BulkEdit,
SessionSettings,
SessionToast,
SessionToggle,
SessionModal,
SessionDropdown,
MediaGallery,
Message,
MessageBody,

@ -0,0 +1,32 @@
/* global Whisper */
// eslint-disable-next-line func-names
(function() {
'use strict';
window.Whisper = window.Whisper || {};
Whisper.SessionDropdownView = Whisper.View.extend({
initialize(options) {
this.props = {
items: options.items,
};
this.render();
},
render() {
this.dropdownView = new Whisper.ReactWrapperView({
className: 'session-dropdown-wrapper',
Component: window.Signal.Components.SessionDropdown,
props: this.props,
});
this.$el.append(this.dropdownView.el);
},
openDropdown() {},
closeDropdown() {},
});
})();

@ -0,0 +1,28 @@
/* global i18n, Whisper */
// eslint-disable-next-line func-names
(function() {
'use strict';
window.Whisper = window.Whisper || {};
Whisper.SessionSettingsView = Whisper.View.extend({
initialize() {
this.render();
},
render() {
this.settingsView = new Whisper.ReactWrapperView({
className: 'session-settings',
Component: window.Signal.Components.SessionSettings,
props: {
i18n,
},
});
this.$el.append(this.settingsView.el);
},
close() {
this.remove();
},
});
})();

@ -0,0 +1,31 @@
/* global Whisper */
// eslint-disable-next-line func-names
(function() {
'use strict';
window.Whisper = window.Whisper || {};
Whisper.SessionToggleView = Whisper.View.extend({
initialize(options) {
this.props = {
active: options.active,
};
},
render() {
this.toggleView = new Whisper.ReactWrapperView({
className: 'session-toggle-wrapper',
Component: window.Signal.Components.SessionToggle,
props: this.props,
});
this.$el.append(this.toggleView.el);
},
toggle() {
this.props.active = !this.props.active;
this.toggleView.update(this.props);
},
});
})();

@ -60,7 +60,7 @@ $session-opaque-dark-3: rgba(0, 0, 0, 0.5);
$session-color-white: #fff;
$session-color-dark-grey: #353535;
$session-color-black: #000;
$session-color-danger: #ff4538;
$session-color-danger: #ff453a;
$session-color-primary: $session-shade-13;
$session-color-secondary: $session-shade-16;
@ -78,6 +78,16 @@ $session-margin-sm: 10px;
$session-margin-md: 15px;
$session-margin-lg: 20px;
div.spacer-sm {
height: $session-margin-sm;
}
div.spacer-md {
height: $session-margin-md;
}
div.spacer-lg {
height: $session-margin-lg;
}
@mixin session-color-subtle($color) {
color: rgba($color, 0.6);
}
@ -173,6 +183,9 @@ $session_message-container-border-radius: 5px;
&.secondary {
background-color: $session-color-secondary;
}
&.success {
background-color: $session-color-success;
}
&.danger {
background-color: $session-color-danger;
}
@ -489,3 +502,191 @@ label {
@include set-toast-theme($session-color-error);
}
}
.session-modal {
z-index: 150;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
box-sizing: border-box;
max-height: 70vh;
max-width: 70vw;
background-color: $session-shade-4;
border: 1px solid $session-shade-8;
&__header {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: $session-margin-lg;
font-family: 'Wasa';
text-align: center;
line-height: 18px;
font-size: 15px;
font-weight: 700;
&__icons,
&__close {
width: 60px;
}
&__icons {
float: right;
}
&__close > div {
float: left;
}
&__icons > div {
float: right;
padding-left: 10px;
}
}
&__body {
padding: $session-margin-lg;
font-family: 'Wasa';
line-height: 16px;
font-size: 13px;
.message {
text-align: center;
}
}
&__button-group {
display: flex;
justify-content: flex-end;
&__center {
align-items: center;
}
.session-button {
margin-left: $session-margin-sm;
}
}
}
.session-toggle {
width: 51px;
height: 31px;
border: 1.5px solid #e5e5ea;
border-radius: 16px;
position: relative;
cursor: pointer;
background-color: rgba(0, 0, 0, 0);
.knob {
position: absolute;
top: 0.5px;
left: 0.5px;
height: 27px;
width: 27px;
border-radius: 28px;
background-color: $session-color-white;
box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.05), 0 3px 1px 0 rgba(0, 0, 0, 0.05),
0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 3px 3px 0 rgba(0, 0, 0, 0.05);
transition: transform 0.25s ease, background-color 0.25s ease;
}
&.active {
background-color: $session-color-green;
border-color: $session-color-green;
.knob {
transform: translateX(20px);
}
}
}
.react-contextmenu {
padding: 0px;
margin: 0px;
border: none !important;
border-radius: 0px;
}
.react-contextmenu-item {
display: flex;
align-items: center;
height: 25px;
padding: 0px 10px;
background-color: #1b1b1b;
color: $session-color-white;
font-family: 'Wasa';
font-size: 12px;
line-height: $session-icon-size-sm;
font-weight: 700;
&--active,
&--selected {
background-color: $session-shade-7 !important;
}
&:active,
&:visited,
&:focus {
outline: none;
}
}
.session-dropdown {
position: absolute;
top: 50px;
left: 50px;
display: inline-block;
ul {
display: block;
list-style: none;
padding: 0px;
margin: 0px;
li {
cursor: pointer;
height: 25px;
padding-right: 7px;
background-color: #1b1b1b;
color: $session-color-white;
font-family: 'Wasa';
font-size: 10px;
line-height: $session-icon-size-sm;
font-weight: 700;
display: flex;
align-items: center;
.session-icon {
margin-left: 6px;
}
.item-content {
margin-left: 6px;
}
&.active,
&:hover {
background-color: $session-shade-7;
}
&.danger {
color: $session-color-danger;
}
}
}
}
.edit-profile-dialog .image-upload-section {
position: absolute;
margin-top: 50px;
margin-left: 75px;
}

@ -1,5 +1,8 @@
import React from 'react';
import { SessionModal } from './session/SessionModal';
import { SessionButton } from './session/SessionButton';
interface Props {
titleText: string;
messageText: string;
@ -16,18 +19,27 @@ export class ConfirmDialog extends React.Component<Props> {
public render() {
return (
<div className="content">
<p className="titleText">{this.props.titleText}</p>
<SessionModal
title={this.props.titleText}
onClose={() => null}
onOk={() => null}
>
<div className="spacer-md" />
<p className="messageText">{this.props.messageText}</p>
<div className="buttons">
<button className="cancel" tabIndex={0} onClick={this.props.onClose}>
{this.props.cancelText}
</button>
<button className="ok" tabIndex={0} onClick={this.props.onConfirm}>
{this.props.okText}
</button>
<div className="spacer-md" />
<div className="session-modal__button-group">
<SessionButton
text={this.props.okText}
onClick={this.props.onConfirm}
/>
<SessionButton
text={this.props.cancelText}
onClick={this.props.onClose}
/>
</div>
</div>
</SessionModal>
);
}
}

@ -2,6 +2,14 @@ import React from 'react';
import classNames from 'classnames';
import { Avatar } from './Avatar';
import { SessionButton, SessionButtonColor } from './session/SessionButton';
import {
SessionIconButton,
SessionIconSize,
SessionIconType,
} from './session/icon';
import { SessionModal } from './session/SessionModal';
declare global {
interface Window {
displayNameRegex: any;
@ -63,11 +71,15 @@ export class EditProfileDialog extends React.Component<Props, State> {
);
return (
<div className="content">
<SessionModal
title={i18n('editProfileModalTitle')}
onOk={this.onClickOK}
onClose={this.closeDialog}
>
<div className="avatar-center">
<div className="avatar-center-inner">
{this.renderAvatar()}
<div className="upload-btn-background">
<div className="image-upload-section">
<input
type="file"
ref={this.inputEl}
@ -76,9 +88,10 @@ export class EditProfileDialog extends React.Component<Props, State> {
name="name"
onChange={this.onFileSelected}
/>
<div
role="button"
className={'module-message__buttons__upload'}
<SessionIconButton
iconType={SessionIconType.Upload}
iconSize={SessionIconSize.Large}
onClick={() => {
const el = this.inputEl.current;
if (el) {
@ -89,6 +102,9 @@ export class EditProfileDialog extends React.Component<Props, State> {
</div>
</div>
</div>
<div className="spacer md" />
<input
type="text"
className="profile-name"
@ -101,15 +117,22 @@ export class EditProfileDialog extends React.Component<Props, State> {
/>
<div className="message">{i18n('editProfileDisplayNameWarning')}</div>
<span className={errorMessageClasses}>{this.state.errorMessage}</span>
<div className="buttons">
<button className="cancel" tabIndex={0} onClick={this.closeDialog}>
{cancelText}
</button>
<button className="ok" tabIndex={0} onClick={this.onClickOK}>
{okText}
</button>
<div className="spacer-lg" />
<div className="session-modal__button-group">
<SessionButton
text={okText}
buttonColor={SessionButtonColor.Secondary}
onClick={this.onClickOK}
/>
<SessionButton
text={cancelText}
buttonColor={SessionButtonColor.Primary}
onClick={this.closeDialog}
/>
</div>
</div>
</SessionModal>
);
}

@ -1,11 +1,12 @@
import React from 'react';
import { Avatar } from './Avatar';
declare global {
interface Window {
displayNameRegex: any;
}
}
import { SessionModal } from './session/SessionModal';
import {
SessionButton,
SessionButtonColor,
SessionButtonType,
} from './session/SessionButton';
interface Props {
i18n: any;
@ -30,31 +31,26 @@ export class UserDetailsDialog extends React.Component<Props> {
public render() {
const i18n = this.props.i18n;
const cancelText = i18n('cancel');
const startConversation = i18n('startConversation');
return (
<div className="content">
<SessionModal
title={this.props.profileName}
onOk={() => null}
onClose={this.closeDialog}
>
<div className="avatar-center">
<div className="avatar-center-inner">{this.renderAvatar()}</div>
</div>
<div className="profile-name">{this.props.profileName}</div>
<div className="message">{this.props.pubkey}</div>
<div className="buttons">
<button className="cancel" tabIndex={0} onClick={this.closeDialog}>
{cancelText}
</button>
<button
className="ok"
tabIndex={0}
<div className="session-modal__button-group__center">
<SessionButton
text={i18n('startConversation')}
buttonType={SessionButtonType.Default}
buttonColor={SessionButtonColor.Primary}
onClick={this.onClickStartConversation}
>
{startConversation}
</button>
/>
</div>
</div>
</SessionModal>
);
}

@ -22,6 +22,8 @@ import {
SessionButtonType,
} from '../session/SessionButton';
import { SessionDropdownTrigger } from '../session/SessionDropdownTrigger';
interface TimerOption {
name: string;
value: number;
@ -245,12 +247,12 @@ export class ConversationHeader extends React.Component<Props> {
}
return (
<ContextMenuTrigger id={triggerId} ref={this.menuTriggerRef}>
<SessionDropdownTrigger>
<SessionIconButton
iconType={SessionIconType.Ellipses}
iconSize={SessionIconSize.Large}
/>
</ContextMenuTrigger>
</SessionDropdownTrigger>
);
}

@ -2,6 +2,8 @@ import React from 'react';
import classNames from 'classnames';
import { Contact, MemberList } from './MemberList';
import { SessionModal } from './../session/SessionModal';
declare global {
interface Window {
Lodash: any;
@ -92,8 +94,7 @@ export class CreateGroupDialog extends React.Component<Props, State> {
);
return (
<div className="content">
<p className="titleText">{titleText}</p>
<SessionModal title={titleText} onClose={() => null} onOk={() => null}>
<p className={errorMessageClasses}>{this.state.errorMessage}</p>
<input
type="text"
@ -123,7 +124,7 @@ export class CreateGroupDialog extends React.Component<Props, State> {
{okText}
</button>
</div>
</div>
</SessionModal>
);
}

@ -2,6 +2,8 @@ import React from 'react';
import classNames from 'classnames';
import { Contact, MemberList } from './MemberList';
import { SessionModal } from './../session/SessionModal';
declare global {
interface Window {
SMALL_GROUP_SIZE_LIMIT: number;
@ -105,9 +107,11 @@ export class UpdateGroupDialog extends React.Component<Props, State> {
);
return (
<div className="content">
<p className="titleText">{titleText}</p>
<SessionModal title={titleText} onClose={() => null} onOk={() => null}>
<div className="spacer-md" />
<p className={errorMessageClasses}>{errorMsg}</p>
<div className="spacer-md" />
<input
type="text"
id="group-name"
@ -121,6 +125,7 @@ export class UpdateGroupDialog extends React.Component<Props, State> {
aria-required={true}
autoFocus={true}
/>
<div className="friend-selection-list">
<MemberList
members={this.state.friendList}
@ -140,7 +145,7 @@ export class UpdateGroupDialog extends React.Component<Props, State> {
{okText}
</button>
</div>
</div>
</SessionModal>
);
}

@ -16,6 +16,7 @@ export enum SessionButtonColor {
White = 'white',
Primary = 'primary',
Secondary = 'secondary',
Success = 'success',
Danger = 'danger',
Warning = 'warning',
}

@ -0,0 +1,81 @@
import React from 'react';
import classNames from 'classnames';
import { SessionIconType } from './icon/';
import {
SessionDropdownItem,
SessionDropDownItemType,
} from './SessionDropdownItem';
// THIS IS A FUTURE-PROOFING ELEMENT TO REPLACE ELECTRON CONTEXTMENUS IN PRELOAD.JS
interface State {
x: number;
y: number;
isVisible: boolean;
}
interface Props {
id?: string;
onClick?: any;
relativeTo: string | Array<number>;
items: Array<{
content: string;
id?: string;
icon?: SessionIconType | null;
type?: SessionDropDownItemType;
active?: boolean;
onClick?: any;
display?: boolean;
}>;
}
export class SessionDropdown extends React.Component<Props, State> {
constructor(props: any) {
super(props);
this.state = {
x: 0,
y: 0,
isVisible: false,
};
}
public show() {
this.setState({
isVisible: true,
});
}
public hide() {
this.setState({
isVisible: false,
});
}
public render() {
const { items } = this.props;
const { isVisible } = this.state;
return (
<div className={classNames('session-dropdown')}>
<ul>
{isVisible
? items.map((item: any) => {
return item.display ? (
<SessionDropdownItem
id={item.id}
content={item.content}
icon={item.icon}
type={item.type}
active={item.active}
onClick={item.onClick}
/>
) : null;
})
: null}
</ul>
</div>
);
}
}

@ -0,0 +1,60 @@
import React from 'react';
import classNames from 'classnames';
import { SessionIcon, SessionIconSize, SessionIconType } from './icon/';
export enum SessionDropDownItemType {
Default = 'default',
Danger = 'danger',
}
interface Props {
id: string;
content: string;
type: SessionDropDownItemType;
icon: SessionIconType | null;
active: boolean;
onClick: any;
}
export class SessionDropdownItem extends React.PureComponent<Props> {
public static defaultProps = {
type: SessionDropDownItemType.Default,
icon: null,
active: false,
onClick: () => null,
};
constructor(props: any) {
super(props);
this.clickHandler = this.clickHandler.bind(this);
}
public render() {
const { content, type, icon, active } = this.props;
const id = this.props.id || window.generateID();
return (
<li
id={id}
className={classNames(active ? 'active' : '', type || '')}
role="button"
onClick={this.clickHandler}
>
{icon ? (
<SessionIcon iconType={icon} iconSize={SessionIconSize.Small} />
) : (
''
)}
<div className="item-content">{content}</div>
</li>
);
}
private clickHandler(e: any) {
if (this.props.onClick) {
e.stopPropagation();
this.props.onClick();
}
}
}

@ -0,0 +1,37 @@
import React from 'react';
interface Props {
//mouseButton: Number;
posX: number;
posY: number;
}
export class SessionDropdownTrigger extends React.Component<Props> {
public static defaultProps = {
//mouseButton: 2, // 0 is left click, 2 is right click
posX: 0,
posY: 0,
};
constructor(props: any) {
super(props);
}
public handleDropdownClick = (event: any) => {
event.preventDefault();
event.stopPropagation();
let x = event.clientX || (event.touches && event.touches[0].pageX);
let y = event.clientY || (event.touches && event.touches[0].pageY);
if (this.props.posX) {
x -= this.props.posX;
}
if (this.props.posY) {
y -= this.props.posY;
}
};
public render() {
return <div role="button" onClick={this.handleDropdownClick} />;
}
}

@ -0,0 +1,90 @@
import React from 'react';
import classNames from 'classnames';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon/';
interface Props {
title: string;
onClose: any;
onOk: any;
//Maximum of two icons in header
headerIconButtons?: Array<{
type: SessionIconType;
onClick?: any;
}>;
}
interface State {
isVisible: boolean;
}
export class SessionModal extends React.PureComponent<Props, State> {
constructor(props: any) {
super(props);
this.state = {
isVisible: true,
};
this.close = this.close.bind(this);
this.onKeyUp = this.onKeyUp.bind(this);
window.addEventListener('keyup', this.onKeyUp);
}
public render() {
const { title, headerIconButtons } = this.props;
const { isVisible } = this.state;
return isVisible ? (
<div className={classNames('session-modal')}>
<div className="session-modal__header">
<div className="session-modal__header__close">
<SessionIconButton
iconType={SessionIconType.Exit}
iconSize={SessionIconSize.Small}
onClick={this.close}
/>
</div>
<div className="session-modal__header__title">{title}</div>
<div className="session-modal__header__icons">
{headerIconButtons
? headerIconButtons.map((iconItem: any) => {
return (
<SessionIconButton
key={iconItem.type}
iconType={iconItem.type}
iconSize={SessionIconSize.Medium}
/>
);
})
: null}
</div>
</div>
<div className="session-modal__body">{this.props.children}</div>
</div>
) : null;
}
public close() {
this.setState({
isVisible: false,
});
window.removeEventListener('keyup', this.onKeyUp);
this.props.onClose();
}
public onKeyUp(event: any) {
switch (event.key) {
case 'Enter':
this.props.onOk();
break;
case 'Esc':
case 'Escape':
this.close();
break;
default:
}
}
}

@ -0,0 +1,17 @@
import React from 'react';
interface Props {
i18n: any;
}
export class SessionSettings extends React.Component<Props> {
constructor(props: any) {
super(props);
}
public render() {
const i18n = this.props.i18n;
return <div />;
}
}

@ -0,0 +1,54 @@
import React from 'react';
import classNames from 'classnames';
interface Props {
active: boolean;
onClick: any;
}
interface State {
active: boolean;
}
export class SessionToggle extends React.PureComponent<Props, State> {
public static defaultProps = {
onClick: () => null,
};
constructor(props: any) {
super(props);
this.clickHandler = this.clickHandler.bind(this);
const { active } = this.props;
this.state = {
active: active,
};
}
public render() {
return (
<div
className={classNames(
'session-toggle',
this.state.active ? 'active' : ''
)}
role="button"
onClick={this.clickHandler}
>
<div className="knob" />
</div>
);
}
private clickHandler(e: any) {
this.setState({
active: !this.state.active,
});
if (this.props.onClick) {
e.stopPropagation();
this.props.onClick();
}
}
}

@ -26,6 +26,7 @@ export enum SessionIconType {
Star = 'star',
QR = 'qr',
Users = 'users',
Upload = 'upload',
Warning = 'warning',
}
@ -171,6 +172,11 @@ export const icons = {
'M9.38,2.17c-1.73,0-3.12,1.4-3.12,3.12s1.4,3.12,3.12,3.12s3.12-1.4,3.12-3.12S11.1,2.17,9.38,2.17z M16.93,0.25c2.3,0.59,3.92,2.67,3.92,5.05s-1.61,4.46-3.92,5.05c-0.56,0.14-1.12-0.19-1.27-0.75c-0.14-0.56,0.19-1.12,0.75-1.27 c1.38-0.35,2.35-1.6,2.35-3.03s-0.97-2.67-2.35-3.03c-0.56-0.14-0.9-0.71-0.75-1.27C15.8,0.44,16.37,0.11,16.93,0.25z M9.38,0.08 c2.88,0,5.21,2.33,5.21,5.21s-2.33,5.21-5.21,5.21S4.17,8.17,4.17,5.29C4.17,2.42,6.5,0.08,9.38,0.08z M21.09,12.75 c2.22,0.57,3.8,2.53,3.9,4.81L25,17.79v2.08c0,0.58-0.47,1.04-1.04,1.04c-0.54,0-0.98-0.41-1.04-0.93l-0.01-0.11v-2.08 c0-1.42-0.96-2.67-2.34-3.02c-0.56-0.14-0.89-0.71-0.75-1.27C19.97,12.94,20.54,12.61,21.09,12.75z M13.54,12.58 c2.8,0,5.09,2.21,5.2,4.99v0.22v2.08c0,0.58-0.47,1.04-1.04,1.04c-0.54,0-0.98-0.41-1.04-0.93l-0.01-0.11v-2.08 c0-1.67-1.3-3.03-2.95-3.12h-0.18H5.21c-1.67,0-3.03,1.3-3.12,2.95v0.18v2.08c0,0.58-0.47,1.04-1.04,1.04 c-0.54,0-0.98-0.41-1.04-0.93L0,19.88V17.8c0-2.8,2.21-5.09,4.99-5.2h0.22h8.33V12.58z',
viewBox: '0 0 25 21',
},
[SessionIconType.Upload]: {
path:
'M380.032,133.472l-112-128C264.992,2.016,260.608,0,256,0c-4.608,0-8.992,2.016-12.032,5.472l-112,128 c-4.128,4.736-5.152,11.424-2.528,17.152C132.032,156.32,137.728,160,144,160h64v208c0,8.832,7.168,16,16,16h64 c8.832,0,16-7.168,16-16V160h64c6.272,0,11.968-3.648,14.56-9.376C385.152,144.896,384.192,138.176,380.032,133.472z M432,352v96H80v-96H16v128c0,17.696,14.336,32,32,32h416c17.696,0,32-14.304,32-32V352H432z',
viewBox: '0 0 512 512',
},
[SessionIconType.Warning]: {
path:
'M243.225,333.382c-13.6,0-25,11.4-25,25s11.4,25,25,25c13.1,0,25-11.4,24.4-24.4 C268.225,344.682,256.925,333.382,243.225,333.382z M474.625,421.982c15.7-27.1,15.8-59.4,0.2-86.4l-156.6-271.2c-15.5-27.3-43.5-43.5-74.9-43.5s-59.4,16.3-74.9,43.4 l-156.8,271.5c-15.6,27.3-15.5,59.8,0.3,86.9c15.6,26.8,43.5,42.9,74.7,42.9h312.8 C430.725,465.582,458.825,449.282,474.625,421.982z M440.625,402.382c-8.7,15-24.1,23.9-41.3,23.9h-312.8 c-17,0-32.3-8.7-40.8-23.4c-8.6-14.9-8.7-32.7-0.1-47.7l156.8-271.4c8.5-14.9,23.7-23.7,40.9-23.7c17.1,0,32.4,8.9,40.9,23.8 l156.7,271.4C449.325,369.882,449.225,387.482,440.625,402.382z M237.025,157.882c-11.9,3.4-19.3,14.2-19.3,27.3c0.6,7.9,1.1,15.9,1.7,23.8c1.7,30.1,3.4,59.6,5.1,89.7 c0.6,10.2,8.5,17.6,18.7,17.6c10.2,0,18.2-7.9,18.7-18.2c0-6.2,0-11.9,0.6-18.2c1.1-19.3,2.3-38.6,3.4-57.9 c0.6-12.5,1.7-25,2.3-37.5c0-4.5-0.6-8.5-2.3-12.5C260.825,160.782,248.925,155.082,237.025,157.882z',

1
ts/global.d.ts vendored

@ -12,6 +12,7 @@ interface Window {
textsecure: any;
Session: any;
i18n: any;
generateID: any;
}
interface Promise<T> {

Loading…
Cancel
Save