Modify design according to the design team
This commit is contained in:
parent
c81bac1a4c
commit
3d4d1d32d9
6 changed files with 154 additions and 89 deletions
|
@ -9,6 +9,34 @@
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.mx_ExportDialog_Exporting .mx_ExportDialog_options {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_ExportDialog_progress {
|
||||||
|
.mx_Dialog_buttons {
|
||||||
|
margin-top: unset;
|
||||||
|
margin-left: 18px;
|
||||||
|
}
|
||||||
|
.mx_ExportDialog_spinner {
|
||||||
|
animation: mx_rotate 2s linear infinite;
|
||||||
|
z-index: 2;
|
||||||
|
position: relative;
|
||||||
|
margin-right: 10px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
& .mx_ExportDialog_spinner_path {
|
||||||
|
stroke: #0dbd8b;
|
||||||
|
stroke-linecap: round;
|
||||||
|
animation: mx_dash 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_RadioButton > .mx_RadioButton_content {
|
.mx_RadioButton > .mx_RadioButton_content {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
|
@ -22,3 +50,24 @@
|
||||||
padding: 9px 10px;
|
padding: 9px 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes mx_rotate {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes mx_dash {
|
||||||
|
0% {
|
||||||
|
stroke-dasharray: 1, 150;
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
stroke-dasharray: 90, 150;
|
||||||
|
stroke-dashoffset: -35;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dasharray: 90, 150;
|
||||||
|
stroke-dashoffset: -124;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -197,6 +197,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let messageCount = null;
|
let messageCount = null;
|
||||||
if (exportType === exportTypes.LAST_N_MESSAGES) {
|
if (exportType === exportTypes.LAST_N_MESSAGES) {
|
||||||
messageCount = (
|
messageCount = (
|
||||||
|
@ -254,72 +255,6 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
|
||||||
/>
|
/>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
);
|
);
|
||||||
} else if (!isExporting) {
|
|
||||||
// Display export settings
|
|
||||||
return (
|
|
||||||
<BaseDialog
|
|
||||||
title={_t("Export Chat")}
|
|
||||||
className="mx_ExportDialog"
|
|
||||||
contentId="mx_Dialog_content"
|
|
||||||
hasCancel={true}
|
|
||||||
onFinished={onFinished}
|
|
||||||
fixedWidth={true}
|
|
||||||
>
|
|
||||||
<p>
|
|
||||||
{ _t("Select from the options below to export chats from your timeline") }
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<span className="mx_ExportDialog_subheading">{ _t("Format") }</span>
|
|
||||||
|
|
||||||
<StyledRadioGroup
|
|
||||||
name="exportFormat"
|
|
||||||
value={exportFormat}
|
|
||||||
onChange={(key) => setExportFormat(exportFormats[key])}
|
|
||||||
definitions={exportFormatOptions}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span className="mx_ExportDialog_subheading">{ _t("Messages") }</span>
|
|
||||||
|
|
||||||
<Field
|
|
||||||
element="select"
|
|
||||||
value={exportType}
|
|
||||||
onChange={(e) => {
|
|
||||||
setExportType(exportTypes[e.target.value]);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ exportTypeOptions }
|
|
||||||
</Field>
|
|
||||||
{ messageCount }
|
|
||||||
|
|
||||||
<span className="mx_ExportDialog_subheading">{ _t("Size Limit") }</span>
|
|
||||||
|
|
||||||
<Field
|
|
||||||
type="number"
|
|
||||||
autoComplete="off"
|
|
||||||
onValidate={onValidateSize}
|
|
||||||
element="input"
|
|
||||||
ref={sizeLimitRef}
|
|
||||||
value={sizeLimit.toString()}
|
|
||||||
postfixComponent={sizePostFix}
|
|
||||||
onChange={(e) => setSizeLimit(parseInt(e.target.value))}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<StyledCheckbox
|
|
||||||
checked={includeAttachments}
|
|
||||||
onChange={(e) =>
|
|
||||||
setAttachments((e.target as HTMLInputElement).checked)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{ _t("Include Attachments") }
|
|
||||||
</StyledCheckbox>
|
|
||||||
|
|
||||||
<DialogButtons
|
|
||||||
primaryButton={_t("Export")}
|
|
||||||
onPrimaryButtonClick={onExportClick}
|
|
||||||
onCancel={() => onFinished(false)}
|
|
||||||
/>
|
|
||||||
</BaseDialog>
|
|
||||||
);
|
|
||||||
} else if (displayCancel) {
|
} else if (displayCancel) {
|
||||||
// Display cancel warning
|
// Display cancel warning
|
||||||
return (
|
return (
|
||||||
|
@ -346,23 +281,104 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Display progress dialog
|
// Display export settings
|
||||||
return (
|
return (
|
||||||
<BaseDialog
|
<BaseDialog
|
||||||
title={_t("Exporting your data...")}
|
title={_t("Export Chat")}
|
||||||
className="mx_ExportDialog"
|
className={`mx_ExportDialog ${isExporting && "mx_ExportDialog_Exporting"}`}
|
||||||
contentId="mx_Dialog_content"
|
contentId="mx_Dialog_content"
|
||||||
hasCancel={false}
|
hasCancel={true}
|
||||||
onFinished={onFinished}
|
onFinished={onFinished}
|
||||||
fixedWidth={true}
|
fixedWidth={true}
|
||||||
>
|
>
|
||||||
<p ref={exportProgressRef} />
|
<p>
|
||||||
<DialogButtons
|
{ _t(
|
||||||
primaryButton={_t("Cancel")}
|
"Select from the options below to export chats from your timeline",
|
||||||
primaryButtonClass="danger"
|
) }
|
||||||
hasCancel={false}
|
</p>
|
||||||
onPrimaryButtonClick={onCancel}
|
|
||||||
/>
|
<span className="mx_ExportDialog_subheading">
|
||||||
|
{ _t("Format") }
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div className="mx_ExportDialog_options">
|
||||||
|
<StyledRadioGroup
|
||||||
|
name="exportFormat"
|
||||||
|
value={exportFormat}
|
||||||
|
onChange={(key) => setExportFormat(exportFormats[key])}
|
||||||
|
definitions={exportFormatOptions}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span className="mx_ExportDialog_subheading">
|
||||||
|
{ _t("Messages") }
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<Field
|
||||||
|
element="select"
|
||||||
|
value={exportType}
|
||||||
|
onChange={(e) => {
|
||||||
|
setExportType(exportTypes[e.target.value]);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ exportTypeOptions }
|
||||||
|
</Field>
|
||||||
|
{ messageCount }
|
||||||
|
|
||||||
|
<span className="mx_ExportDialog_subheading">
|
||||||
|
{ _t("Size Limit") }
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<Field
|
||||||
|
type="number"
|
||||||
|
autoComplete="off"
|
||||||
|
onValidate={onValidateSize}
|
||||||
|
element="input"
|
||||||
|
ref={sizeLimitRef}
|
||||||
|
value={sizeLimit.toString()}
|
||||||
|
postfixComponent={sizePostFix}
|
||||||
|
onChange={(e) => setSizeLimit(parseInt(e.target.value))}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StyledCheckbox
|
||||||
|
checked={includeAttachments}
|
||||||
|
onChange={(e) =>
|
||||||
|
setAttachments(
|
||||||
|
(e.target as HTMLInputElement).checked,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{ _t("Include Attachments") }
|
||||||
|
</StyledCheckbox>
|
||||||
|
</div>
|
||||||
|
{ isExporting ? (
|
||||||
|
<div className = "mx_ExportDialog_progress">
|
||||||
|
<svg className="mx_ExportDialog_spinner" viewBox="0 0 50 50">
|
||||||
|
<circle
|
||||||
|
className="mx_ExportDialog_spinner_path"
|
||||||
|
cx="25"
|
||||||
|
cy="25"
|
||||||
|
r="20"
|
||||||
|
fill="none"
|
||||||
|
stroke-width="5"
|
||||||
|
></circle>
|
||||||
|
</svg>
|
||||||
|
<p ref={exportProgressRef}>
|
||||||
|
{ _t("Processing...") }
|
||||||
|
</p>
|
||||||
|
<DialogButtons
|
||||||
|
primaryButton={_t("Cancel")}
|
||||||
|
primaryButtonClass="danger"
|
||||||
|
hasCancel={false}
|
||||||
|
onPrimaryButtonClick={onCancel}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<DialogButtons
|
||||||
|
primaryButton={_t("Export")}
|
||||||
|
onPrimaryButtonClick={onExportClick}
|
||||||
|
onCancel={() => onFinished(false)}
|
||||||
|
/>
|
||||||
|
) }
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -730,7 +730,7 @@
|
||||||
"JSON": "JSON",
|
"JSON": "JSON",
|
||||||
"Plain Text": "Plain Text",
|
"Plain Text": "Plain Text",
|
||||||
"From the beginning": "From the beginning",
|
"From the beginning": "From the beginning",
|
||||||
"For a number of messages": "For a number of messages",
|
"Specify a number of messages": "Specify a number of messages",
|
||||||
"Current Timeline": "Current Timeline",
|
"Current Timeline": "Current Timeline",
|
||||||
"Media omitted": "Media omitted",
|
"Media omitted": "Media omitted",
|
||||||
"Media omitted - file size limit exceeded": "Media omitted - file size limit exceeded",
|
"Media omitted - file size limit exceeded": "Media omitted - file size limit exceeded",
|
||||||
|
@ -2272,15 +2272,15 @@
|
||||||
"Okay": "Okay",
|
"Okay": "Okay",
|
||||||
"Export Successful": "Export Successful",
|
"Export Successful": "Export Successful",
|
||||||
"Your messages were successfully exported": "Your messages were successfully exported",
|
"Your messages were successfully exported": "Your messages were successfully exported",
|
||||||
|
"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",
|
||||||
"Export Chat": "Export Chat",
|
"Export Chat": "Export Chat",
|
||||||
"Select from the options below to export chats from your timeline": "Select from the options below to export chats from your timeline",
|
"Select from the options below to export chats from your timeline": "Select from the options below to export chats from your timeline",
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Size Limit": "Size Limit",
|
"Size Limit": "Size Limit",
|
||||||
"Include Attachments": "Include Attachments",
|
"Include Attachments": "Include Attachments",
|
||||||
|
"Processing...": "Processing...",
|
||||||
"Export": "Export",
|
"Export": "Export",
|
||||||
"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...",
|
|
||||||
"Feedback sent": "Feedback sent",
|
"Feedback sent": "Feedback sent",
|
||||||
"Rate %(brand)s": "Rate %(brand)s",
|
"Rate %(brand)s": "Rate %(brand)s",
|
||||||
"Tell us below how you feel about %(brand)s so far.": "Tell us below how you feel about %(brand)s so far.",
|
"Tell us below how you feel about %(brand)s so far.": "Tell us below how you feel about %(brand)s so far.",
|
||||||
|
|
|
@ -44,7 +44,7 @@ export default abstract class Exporter {
|
||||||
|
|
||||||
protected updateProgress(progress: string, log = true, show = true): void {
|
protected updateProgress(progress: string, log = true, show = true): void {
|
||||||
if (log) console.log(progress);
|
if (log) console.log(progress);
|
||||||
if (show) this.exportProgressRef.current.innerText = progress;
|
if (show && this.exportProgressRef.current) this.exportProgressRef.current.innerText = progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected addFile(filePath: string, blob: Blob): void {
|
protected addFile(filePath: string, blob: Blob): void {
|
||||||
|
@ -64,7 +64,7 @@ export default abstract class Exporter {
|
||||||
// Create a writable stream to the directory
|
// Create a writable stream to the directory
|
||||||
this.fileStream = streamSaver.createWriteStream(filename);
|
this.fileStream = streamSaver.createWriteStream(filename);
|
||||||
|
|
||||||
if (!this.cancelled) this.updateProgress("Generating a ZIP...");
|
if (!this.cancelled) this.updateProgress("Generating a ZIP");
|
||||||
else return this.cleanUp();
|
else return this.cleanUp();
|
||||||
|
|
||||||
this.writer = this.fileStream.getWriter();
|
this.writer = this.fileStream.getWriter();
|
||||||
|
@ -79,7 +79,7 @@ export default abstract class Exporter {
|
||||||
|
|
||||||
if (this.cancelled) return this.cleanUp();
|
if (this.cancelled) return this.cleanUp();
|
||||||
|
|
||||||
this.updateProgress("Writing to the file system...");
|
this.updateProgress("Writing to the file system");
|
||||||
|
|
||||||
const reader = readableZipStream.getReader();
|
const reader = readableZipStream.getReader();
|
||||||
await this.pumpToFileStream(reader);
|
await this.pumpToFileStream(reader);
|
||||||
|
@ -186,8 +186,8 @@ export default abstract class Exporter {
|
||||||
}
|
}
|
||||||
this.updateProgress(
|
this.updateProgress(
|
||||||
("Fetched " + events.length + " events ") + (this.exportType === exportTypes.LAST_N_MESSAGES
|
("Fetched " + events.length + " events ") + (this.exportType === exportTypes.LAST_N_MESSAGES
|
||||||
? `out of ${this.exportOptions.numberOfMessages}...`
|
? `out of ${this.exportOptions.numberOfMessages}`
|
||||||
: "so far..."),
|
: "so far"),
|
||||||
);
|
);
|
||||||
prevToken = res.end;
|
prevToken = res.end;
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,8 +361,8 @@ export default class HTMLExporter extends Exporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async export() {
|
public async export() {
|
||||||
this.updateProgress("Starting export process...", true, false);
|
this.updateProgress("Starting export process", true, false);
|
||||||
this.updateProgress("Fetching events...");
|
this.updateProgress("Fetching events");
|
||||||
|
|
||||||
const fetchStart = performance.now();
|
const fetchStart = performance.now();
|
||||||
const res = await this.getRequiredEvents();
|
const res = await this.getRequiredEvents();
|
||||||
|
|
|
@ -29,7 +29,7 @@ export const textForType = (type: string): string => {
|
||||||
case exportTypes.BEGINNING:
|
case exportTypes.BEGINNING:
|
||||||
return _t("From the beginning");
|
return _t("From the beginning");
|
||||||
case exportTypes.LAST_N_MESSAGES:
|
case exportTypes.LAST_N_MESSAGES:
|
||||||
return _t("For a number of messages");
|
return _t("Specify a number of messages");
|
||||||
case exportTypes.TIMELINE:
|
case exportTypes.TIMELINE:
|
||||||
return _t("Current Timeline");
|
return _t("Current Timeline");
|
||||||
// case exportTypes.START_DATE:
|
// case exportTypes.START_DATE:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue