You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/components/session/SessionChannelSettings.tsx

271 lines
7.4 KiB
TypeScript

Session v1.0 changes (#802) * correct typo in readme * include log * decrypt file server response, remove debug, handle crypt before _sendToProxy, improve json parsing failure logging * support file uploads on file proxy, fix _sendToProxy calling * bump form-data to 3.0 * initial refactor of feaure flag detection statements in serverRequest() * fix send-message line-height with multiple lines * fix lint * fix position of delete account modal * Profile picture upload, fixes and copy * Various changes suggested by redesign overview * Scrolling button updated and animations to modals * Display subscriber count for open chats * Prevent illegal username and passwords * Delete channel / group merge * Solidification of minor changes w appview injections * hide description field in group panel for now * fix join publicgroups pulls * increase min height respecting ratio * allow space inside a display name but not at start or end * fix height of leftpane overlay view * add back typing indicator and read receipt setting under privacy * Auto-focus new open chat input box * Password lock screen and delete data screen * touchups * Resolving Bilb revisions * Disable link previews as default per Kee on signup * remove date, we have git * add missing semicolon * _sendToProxy pass headers/handle response refactor, lint * fix my yarn conflict/resolve * include IV in server response * Sealed sender support * Support sealed sender for friend requests * fix lint * Remove unused destinationRegistrationId; lint * Update messages.json * pull RSS through file proxy * fix unit tests: remove not used count in scrolldown view and assert svg present * Disable auto-joining default loki open groups * session-id-editable-textarea * fix the textscramble for sessionID on registration * speed up lint, add lint-full/format-full, make sure use lint-full * add skipToken to establishConnection options, smuggle out secureRpcPubKey * get latest version through snode proxy, remove clearfix from ExpiredAlertBanner * expose semver and LokiAppDotNetServerAPI because we can't get ourKey from storage early enough * update note * fix upgrade link, wrap expiredWarning in span for styling, use br to clear the float, trim trailing whitespace * designalify * designalify * designalify user agent * continue designalification * make expired banner legible * remove ugly TLS hack * disable unauthorization rejection when making https requests limited to lokiRpc * Update main.js Aspect ratio amendment * Constants rework * local commit * event listeners * address missing comma for lint * fix header sessions message section * fix profile image size conversation list with pending friend request * textarea centering * refresh files in group in group panel * Looking into keyboard navigation * Remove P2P * cache eslint on `lint` but not `ready` * Cleanup media view formatting * force locale to be EN until our files are updated and translated * Simplification of keyup * Updated all icon references * SASS fixup * fix disabled state of message input on sent friendrequest * trim pubkey when user can enter one to remove whitespaces * remove lZ in path which fixes errors on svg and does not alter rendering * fix text scramble animation on registration * reload app on ctrl-r or f5 from anywhere * add back file which should have not been deleted * fix lint and clean code * fix lint * add .loki to have a self-signed cert * Remove mixpanel * use local shortcut instead of global shortcut otherwise, ctrl+r is only caught bu the last loaded instance * open the conversation when accepting a friend request also, it does what is needed to show the new friend in the friend list * make sure token comms are done over fileProxy, other notes, logging adjustment * leftpane sections titles are Wasa bold * minor refactor * onboarding messageview * linter * fix padding buttons overlay * do not render session-id-editable border when textarea disabled * textarea sessionID SpaceMono font * various touchups * fix font of description to sfprodisplay * reduce triple dots conversation header icon size * reduce size of conversationHeader title font size * fix font for session-search-input * make conversationlistitem title font wasa * fix green and white border under title in leftpane * fix panel-text-divider font-size and family * disable completely borders for profile images * make profile image which where 48pixels big 36 noew, as no more border * Complete conditional message onboarding * cache file deletions * Link preview warning on setting toggle * Messages.json amendments * Join channel generalisation * Localise global vars * remove eslintcache * rm global launchcount * Remove source field from envelope * Session public chat icon * CLosed groups ui initial listprops * Desktop: enable useSnodeProxy feature flag * file proxy needs to be able to talk to snode - disable TLS check for fileProxy - lokiHttpsAgent => snodeHttpsAgent (since we use for two different things now) * enable useSealedSender too per Maxim * lint * lint * window.extension.expiredPromise version * better error checking * use promise version to see if we're expired * fix typo * lint * put back seemingly now required process.env.NODE_TLS_REJECT_UNAUTHORIZED * fix querystring in file-proxy * lint * fix typo * Remove more references to signal.org * make sure TLS is forced on open groups, improve serverRequest error message * Closed groups UI * function params changes * turn off snode proxy logging * include useful info on error * actually validate URL before starting up a bunch of timers * Closed groups overlay integration * move comments from connecting_to_server_dialog_view * use attempt from window object to reduce code duplication * refactor out validServer() * lint * lint caught typo * Rename BACKGROUND_FRIEND_REQUEST to SESSION_REQUEST. Don't trigger friend request logic if a message is aimed at a group. * Linting * Closed group joining completed w/o backend * Fix friend request messages being sent to users you don't have a session in closed groups. Disable typing messages and read receipts in groups. Send out session request messages if you don't have a session with a member in the group. * Remove unneeded boolean condition. * Closed group update message stylgin * constants renaming * Message deletion fix * gruntify * fix grunt error * expose isRss, don't close uncloseable Rss conversation on deleteMessages * remove copyId and block user on RSS feeds * remove options from RSS feed that don't make any sense and don't work * fix grunt error * squelch RSS duplicate messages * extension.expiredStatus(), adjustable timers, improve guards * allowing sending of messages if we're still waiting to hear back * markRandomNodeUnreachable() refactor, notes/logging * improve logging * improve logging * no need to validate empty token, support lokinet/getession file domains, mark broken snodes as bad, improve logging * try to address travis-osx lint complaints * not designed to have a period at the end of titleIsNow * put period back at the end * Catch a stray loki messenger * fix stray loki messenger * loki messenger isnt a thing * lint * Fix open group joining. * guards incase there are no members yet, fixes dialog not showing up * fixed file server holding up message sender init. fix joining closed groups. * Clean * Don't wait for file server to return tokens when establishing home connection. * Disable join public chat prompt Co-authored-by: Audric Ackermann <audric.bilb@gmail.com> Co-authored-by: Ryan Tharp <neuro@interx.net> Co-authored-by: Vince <vincent@loki.network> Co-authored-by: Maxim Shishmarev <msgmaxim@gmail.com>
5 years ago
import React from 'react';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { Avatar } from '../Avatar';
import {
SessionButton,
SessionButtonColor,
SessionButtonType,
} from './SessionButton';
import { MediaGallery } from '../conversation/media-gallery/MediaGallery';
import _ from 'lodash';
import { TimerOption } from '../conversation/ConversationHeader';
interface Props {
id: string;
name: string;
memberCount: number;
description: string;
avatarPath: string;
timerOptions: Array<TimerOption>;
isPublic: boolean;
onGoBack: () => void;
onInviteFriends: () => void;
onLeaveGroup: () => void;
onShowLightBox: (options: any) => void;
onSetDisappearingMessages: (seconds: number) => void;
}
export class SessionChannelSettings extends React.Component<Props, any> {
public constructor(props: Props) {
super(props);
this.state = {
documents: Array<any>(),
media: Array<any>(),
onItemClick: undefined,
};
}
public componentWillMount() {
this.getMediaGalleryProps()
.then(({ documents, media, onItemClick }) => {
this.setState({
documents,
media,
onItemClick,
});
})
.ignore();
}
public componentDidUpdate() {
this.getMediaGalleryProps()
.then(({ documents, media, onItemClick }) => {
this.setState({
documents,
media,
onItemClick,
});
})
.ignore();
}
public async getMediaGalleryProps() {
// We fetch more documents than media as they dont require to be loaded
// into memory right away. Revisit this once we have infinite scrolling:
const DEFAULT_MEDIA_FETCH_COUNT = 50;
const DEFAULT_DOCUMENTS_FETCH_COUNT = 150;
const conversationId = this.props.id;
const rawMedia = await window.Signal.Data.getMessagesWithVisualMediaAttachments(
conversationId,
{
limit: DEFAULT_MEDIA_FETCH_COUNT,
MessageCollection: window.Whisper.MessageCollection,
}
);
const rawDocuments = await window.Signal.Data.getMessagesWithFileAttachments(
conversationId,
{
limit: DEFAULT_DOCUMENTS_FETCH_COUNT,
MessageCollection: window.Whisper.MessageCollection,
}
);
// First we upgrade these messages to ensure that they have thumbnails
const max = rawMedia.length;
for (let i = 0; i < max; i += 1) {
const message = rawMedia[i];
const { schemaVersion } = message;
if (schemaVersion < message.VERSION_NEEDED_FOR_DISPLAY) {
// Yep, we really do want to wait for each of these
// eslint-disable-next-line no-await-in-loop
rawMedia[i] = await window.Signal.Migrations.upgradeMessageSchema(
message
);
// eslint-disable-next-line no-await-in-loop
await window.Signal.Data.saveMessage(rawMedia[i], {
Message: window.Whisper.Message,
});
}
}
// tslint:disable-next-line: underscore-consistent-invocation
const media = _.flatten(
rawMedia.map((message: { attachments: any }) => {
const { attachments } = message;
return (attachments || [])
.filter(
(attachment: { thumbnail: any; pending: any; error: any }) =>
attachment.thumbnail && !attachment.pending && !attachment.error
)
.map(
(
attachment: { path?: any; contentType?: any; thumbnail?: any },
index: any
) => {
const { thumbnail } = attachment;
return {
objectURL: window.Signal.Migrations.getAbsoluteAttachmentPath(
attachment.path
),
thumbnailObjectUrl: thumbnail
? window.Signal.Migrations.getAbsoluteAttachmentPath(
thumbnail.path
)
: null,
contentType: attachment.contentType,
index,
attachment,
message,
};
}
);
})
);
// Unlike visual media, only one non-image attachment is supported
const documents = rawDocuments.map(
(message: { attachments: Array<any> }) => {
const attachments = message.attachments || [];
const attachment = attachments[0];
return {
contentType: attachment.contentType,
index: 0,
attachment,
message,
};
}
);
const saveAttachment = async ({ attachment, message }: any = {}) => {
const timestamp = message.received_at;
window.Signal.Types.Attachment.save({
attachment,
document,
getAbsolutePath: window.Signal.Migrations.getAbsoluteAttachmentPath,
timestamp,
});
};
const onItemClick = async ({ message, attachment, type }: any) => {
switch (type) {
case 'documents': {
saveAttachment({ message, attachment }).ignore();
break;
}
case 'media': {
const lightBoxOptions = {
media,
attachment,
message,
};
this.onShowLightBox(lightBoxOptions);
break;
}
default:
throw new TypeError(`Unknown attachment type: '${type}'`);
}
};
return {
media,
documents,
onItemClick,
};
}
public onShowLightBox(options: any) {
this.props.onShowLightBox(options);
}
public render() {
const { memberCount, name, onLeaveGroup, isPublic } = this.props;
const { documents, media, onItemClick } = this.state;
const showMemberCount = !!(memberCount && memberCount > 0);
const leaveGroupString = isPublic
? window.i18n('leaveOpenGroup')
: window.i18n('leaveClosedGroup');
return (
<div className="group-settings">
{this.renderHeader()}
<h2>{name}</h2>
{showMemberCount && (
<>
<div className="spacer-lg" />
<div className="text-subtle">
{window.i18n('members', memberCount)}
</div>
<div className="spacer-lg" />
</>
)}
<input
className="description"
placeholder={window.i18n('description')}
/>
<div className="group-settings-item">
{window.i18n('notifications')}
</div>
<div className="group-settings-item">
{window.i18n('disappearingMessages')}
</div>
<MediaGallery
documents={documents}
media={media}
onItemClick={onItemClick}
/>
<SessionButton
text={leaveGroupString}
buttonColor={SessionButtonColor.Danger}
buttonType={SessionButtonType.SquareOutline}
onClick={onLeaveGroup}
/>
</div>
);
}
private renderHeader() {
const { id, onGoBack, onInviteFriends, avatarPath } = this.props;
return (
<div className="group-settings-header">
<SessionIconButton
iconType={SessionIconType.Chevron}
iconSize={SessionIconSize.Medium}
iconRotation={90}
onClick={onGoBack}
/>
<Avatar
avatarPath={avatarPath}
phoneNumber={id}
conversationType="group"
size={80}
/>
<SessionIconButton
iconType={SessionIconType.AddUser}
iconSize={SessionIconSize.Medium}
onClick={onInviteFriends}
/>
</div>
);
}
}