Change export bundle filename format, light theme for all exports and import jszip after export cta

This commit is contained in:
Jaiwanth 2021-09-22 22:17:23 +05:30
parent 94e4fb71c1
commit d1e3d35d40
7 changed files with 178 additions and 135 deletions

View file

@ -20,7 +20,7 @@ limitations under the License.
display: block;
font-family: $font-family;
font-weight: $font-semi-bold;
color: $primary-fg-color;
color: $accent-fg-color;
margin-top: 18px;
margin-bottom: 12px;
}

View file

@ -17,27 +17,26 @@ limitations under the License.
import React, { useRef, useState } from "react";
import { Room } from "matrix-js-sdk/src";
import { _t } from "../../../languageHandler";
import { IDialogProps } from "../../../components/views/dialogs/IDialogProps";
import BaseDialog from "../../../components/views/dialogs/BaseDialog";
import DialogButtons from "../../../components/views/elements/DialogButtons";
import Field from "../../../components/views/elements/Field";
import StyledRadioGroup from "../../../components/views/elements/StyledRadioGroup";
import StyledCheckbox from "../../../components/views/elements/StyledCheckbox";
import { IDialogProps } from "./IDialogProps";
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
import Field from "../elements/Field";
import StyledRadioGroup from "../elements/StyledRadioGroup";
import StyledCheckbox from "../elements/StyledCheckbox";
import {
ExportFormat,
ExportType,
textForFormat,
textForType,
} from "../../../utils/exportUtils/exportUtils";
import withValidation, { IFieldState, IValidationResult } from "../../../components/views/elements/Validation";
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
import HTMLExporter from "../../../utils/exportUtils/HtmlExport";
import JSONExporter from "../../../utils/exportUtils/JSONExport";
import PlainTextExporter from "../../../utils/exportUtils/PlainTextExport";
import { useStateCallback } from "../../../hooks/useStateCallback";
import Exporter from "../../../utils/exportUtils/Exporter";
import Spinner from "../../../components/views/elements/Spinner";
import Modal from "../../../Modal";
import InfoDialog from "../../../components/views/dialogs/InfoDialog";
import Spinner from "../elements/Spinner";
import InfoDialog from "./InfoDialog";
interface IProps extends IDialogProps {
room: Room;
@ -215,11 +214,10 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
};
const confirmCanel = async () => {
await exporter?.cancelExport().then(() => {
setExportCancelled(true);
setExporting(false);
setExporter(null);
});
await exporter?.cancelExport();
setExportCancelled(true);
setExporting(false);
setExporter(null);
};
const exportFormatOptions = Object.keys(ExportFormat).map((format) => ({
@ -256,26 +254,26 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
if (exportCancelled) {
// Display successful cancellation message
Modal.createTrackedDialog("Export Cancelled", "", InfoDialog, {
title: _t("Export Cancelled"),
description: <p>{ _t("The export was cancelled successfully") }</p>,
hasCloseButton: true,
onFinished: () => {
setExportCancelled(false);
},
});
return null;
return (
<InfoDialog
title={_t("Export Successful")}
description={_t("The export was cancelled successfully")}
hasCloseButton={true}
onFinished={onFinished}
/>
);
} else if (exportSuccessful) {
// Display successful export message
Modal.createTrackedDialog("Export Successful", "", InfoDialog, {
title: _t("Export Successful"),
description: <p>{ _t("Your messages were successfully exported") }</p>,
hasCloseButton: true,
onFinished: () => {
setExportSuccessful(false);
},
});
return null;
return (
<InfoDialog
title={_t("Export Successful")}
description={_t(
"Your export was successful. Find it in your Downloads folder.",
)}
hasCloseButton={true}
onFinished={onFinished}
/>
);
} else if (displayCancel) {
// Display cancel warning
return (

View file

@ -47,6 +47,7 @@ import { useRoomMemberCount } from "../../../hooks/useRoomMembers";
import { Container, MAX_PINNED, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
import RoomName from "../elements/RoomName";
import UIStore from "../../../stores/UIStore";
import ExportDialog from "../dialogs/ExportDialog";
interface IProps {
room: Room;
@ -241,7 +242,6 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
};
const onRoomExportClick = async () => {
const { default: ExportDialog } = await import("../../../async-components/views/dialogs/ExportDialog");
Modal.createTrackedDialog('export room dialog', '', ExportDialog, {
room,
});

View file

@ -3061,7 +3061,7 @@
"Export Cancelled": "Export Cancelled",
"The export was cancelled successfully": "The export was cancelled successfully",
"Export Successful": "Export Successful",
"Your messages were successfully exported": "Your messages were successfully exported",
"Your export was successful. Find it in your Downloads folder.": "Your export was successful. Find it in your Downloads folder.",
"Are you sure you want to stop exporting your data? If you do, you'll need to start over.": "Are you sure you want to stop exporting your data? If you do, you'll need to start over.",
"Stop": "Stop",
"Exporting your data": "Exporting your data",

View file

@ -22,9 +22,9 @@ import { decryptFile } from "../DecryptFile";
import { mediaFromContent } from "../../customisations/Media";
import { formatFullDateNoDay } from "../../DateUtils";
import { Direction, MatrixClient } from "matrix-js-sdk";
import JSZip from "jszip";
import { saveAs } from "file-saver";
import { _t } from "../../languageHandler";
import SdkConfig from "../../SdkConfig";
type BlobFile = {
name: string;
@ -71,7 +71,9 @@ export default abstract class Exporter {
}
protected async downloadZIP(): Promise<string | void> {
const filename = `matrix-export-${formatFullDateNoDay(new Date())}.zip`;
const brand = SdkConfig.get().brand;
const filename = `${brand} - Chat Export -${formatFullDateNoDay(new Date())}.zip`;
const { default: JSZip } = await import('jszip');
const zip = new JSZip();
// Create a writable stream to the directory

View file

@ -16,13 +16,12 @@ limitations under the License.
/* eslint-disable max-len, camelcase */
import ThemeWatcher from "../../settings/watchers/ThemeWatcher";
import customCSS from "!!raw-loader!./exportCustomCSS.css";
const getExportCSS = async (): Promise<string> => {
const theme = new ThemeWatcher().getEffectiveTheme();
const stylesheets: string[] = [];
document.querySelectorAll('link[rel="stylesheet"]').forEach((e: any) => {
if (e.href.endsWith("bundle.css") || e.href.endsWith(`theme-${theme}.css`)) {
if (e.href.endsWith("bundle.css") || e.href.endsWith("theme-light.css")) {
stylesheets.push(e.href);
}
});
@ -45,100 +44,6 @@ const getExportCSS = async (): Promise<string> => {
"font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace",
);
const customCSS = `
#snackbar {
display: flex;
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
position: fixed;
z-index: 1;
left: 50%;
bottom: 30px;
font-size: 17px;
padding: 6px 16px;
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Ubuntu, roboto, noto, arial, sans-serif;
font-weight: 400;
line-height: 1.43;
border-radius: 4px;
letter-spacing: 0.01071em;
}
#snackbar.mx_show {
visibility: visible;
-webkit-animation: mx_snackbar_fadein 0.5s, mx_snackbar_fadeout 0.5s 2.5s;
animation: mx_snackbar_fadein 0.5s, mx_snackbar_fadeout 0.5s 2.5s;
}
a.mx_reply_anchor{
cursor: pointer;
color: #238cf5;
}
a.mx_reply_anchor:hover{
text-decoration: underline;
}
@-webkit-keyframes mx_snackbar_fadein {
from {bottom: 0; opacity: 0;}
to {bottom: 30px; opacity: 1;}
}
@keyframes mx_snackbar_fadein {
from {bottom: 0; opacity: 0;}
to {bottom: 30px; opacity: 1;}
}
@-webkit-keyframes mx_snackbar_fadeout {
from {bottom: 30px; opacity: 1;}
to {bottom: 0; opacity: 0;}
}
@keyframes mx_snackbar_fadeout {
from {bottom: 30px; opacity: 1;}
to {bottom: 0; opacity: 0;}
}
* {
scroll-behavior: smooth !important;
}
.mx_Export_EventWrapper:target {
background: ${theme == 'light' ? "white" : "#15191E"};
animation: mx_event_highlight_animation 2s linear;
}
@keyframes mx_event_highlight_animation {
0%,100% {
background: ${theme == 'light' ? "white" : "#15191E"};
}
50% {
background: ${theme == 'light' ? "#e3e2df" : "#21262c"};
}
}
.mx_ReplyThread_Export {
margin-top: 0px;
margin-bottom: 5px;
}
.mx_RedactedBody {
padding-left: unset;
}
img {
white-space: nowrap;
overflow: hidden;
}
.mx_MatrixChat{
max_width: 100%;
}
`;
return CSS + customCSS;
};

View file

@ -0,0 +1,138 @@
/*
Copyright 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is raw-imported (imported as plain text) for the export bundle, which is the reason for the .css format and the colours being hard-coded hard-coded.
*/
#snackbar {
display: flex;
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
position: fixed;
z-index: 1;
left: 50%;
bottom: 30px;
font-size: 17px;
padding: 6px 16px;
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir,
segoe ui, helvetica neue, helvetica, Ubuntu, roboto, noto, arial,
sans-serif;
font-weight: 400;
line-height: 1.43;
border-radius: 4px;
letter-spacing: 0.01071em;
}
#snackbar.mx_show {
visibility: visible;
-webkit-animation: mx_snackbar_fadein 0.5s, mx_snackbar_fadeout 0.5s 2.5s;
animation: mx_snackbar_fadein 0.5s, mx_snackbar_fadeout 0.5s 2.5s;
}
a.mx_reply_anchor {
cursor: pointer;
color: #238cf5;
}
a.mx_reply_anchor:hover {
text-decoration: underline;
}
@-webkit-keyframes mx_snackbar_fadein {
from {
bottom: 0;
opacity: 0;
}
to {
bottom: 30px;
opacity: 1;
}
}
@keyframes mx_snackbar_fadein {
from {
bottom: 0;
opacity: 0;
}
to {
bottom: 30px;
opacity: 1;
}
}
@-webkit-keyframes mx_snackbar_fadeout {
from {
bottom: 30px;
opacity: 1;
}
to {
bottom: 0;
opacity: 0;
}
}
@keyframes mx_snackbar_fadeout {
from {
bottom: 30px;
opacity: 1;
}
to {
bottom: 0;
opacity: 0;
}
}
* {
scroll-behavior: smooth !important;
}
.mx_Export_EventWrapper:target {
background: white;
animation: mx_event_highlight_animation 2s linear;
}
@keyframes mx_event_highlight_animation {
0%,
100% {
background: white;
}
50% {
background: #e3e2df;
}
}
.mx_ReplyThread_Export {
margin-top: 0px;
margin-bottom: 5px;
}
.mx_RedactedBody {
padding-left: unset;
}
img {
white-space: nowrap;
overflow: hidden;
}
.mx_MatrixChat {
max-width: 100%;
}