mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 14:53:33 +00:00
send text details
This commit is contained in:
@@ -2214,6 +2214,10 @@
|
||||
"message": "Send",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendDetails": {
|
||||
"message": "Send details",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"searchSends": {
|
||||
"message": "Search Sends",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
@@ -2246,14 +2250,14 @@
|
||||
"message": "Limit views"
|
||||
},
|
||||
"limitSendViewsHint": {
|
||||
"message": "No one can view this Send after the limit is reached. $ACCESSCOUNT$ views",
|
||||
"message": "No one can view this Send after the limit is reached.",
|
||||
"description": "Displayed under the limit views field on Send"
|
||||
},
|
||||
"limitSendViewsHintWithCount": {
|
||||
"message": "No one can view this Send after the limit is reached. $ACCESSCOUNT$ views left",
|
||||
"description": "Displayed under the limit views field on Send",
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"accessCount": {
|
||||
"content": "$1",
|
||||
"example": "2"
|
||||
}
|
||||
|
||||
@@ -36,5 +36,5 @@ export abstract class SendApiService {
|
||||
renewSendFileUploadUrl: (sendId: string, fileId: string) => Promise<SendFileUploadDataResponse>;
|
||||
removePassword: (id: string) => Promise<any>;
|
||||
delete: (id: string) => Promise<any>;
|
||||
save: (sendData: [Send, EncArrayBuffer]) => Promise<Send>;
|
||||
save: (sendData: [Send, EncArrayBuffer]) => Promise<void>;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { SendId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { ApiService } from "../../../abstractions/api.service";
|
||||
import { ErrorResponse } from "../../../models/response/error.response";
|
||||
import { ListResponse } from "../../../models/response/list.response";
|
||||
@@ -137,13 +135,11 @@ export class SendApiService implements SendApiServiceAbstraction {
|
||||
return this.apiService.send("DELETE", "/sends/" + id, null, true, false);
|
||||
}
|
||||
|
||||
async save(sendData: [Send, EncArrayBuffer]): Promise<Send> {
|
||||
async save(sendData: [Send, EncArrayBuffer]): Promise<void> {
|
||||
const response = await this.upload(sendData);
|
||||
|
||||
const data = new SendData(response);
|
||||
const updated = await this.sendService.upsert(data);
|
||||
// No local data for new Sends
|
||||
return new Send(updated[response.id as SendId]);
|
||||
await this.sendService.upsert(data);
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<any> {
|
||||
|
||||
@@ -22,5 +22,5 @@ export abstract class SendFormService {
|
||||
send: SendView,
|
||||
file: File | ArrayBuffer,
|
||||
config: SendFormConfig,
|
||||
): Promise<SendView>;
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<bit-label>{{ "limitSendViews" | i18n }}</bit-label>
|
||||
<input bitInput type="number" formControlName="maxAccessCount" min="1" />
|
||||
<bit-hint>{{ "limitSendViewsHint" | i18n }}</bit-hint>
|
||||
<bit-hint>{{ "limitSendViewsHintWithCount" | i18n }}</bit-hint>
|
||||
<!-- <bit-hint>{{ "limitSendViewsHintWithCount" | i18n: 4 }}</bit-hint> -->
|
||||
</bit-form-field>
|
||||
<!-- TODO: Add information of current access count as bitHint -->
|
||||
<bit-form-field>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<bit-section [formGroup]="sendTextDetailsForm">
|
||||
<bit-section-header>
|
||||
<!-- TODO: Add i18n for this header -->
|
||||
<h2 bitTypography="h5">Send details</h2>
|
||||
<h2 bitTypography="h5">{{ "sendDetails" | i18n }}</h2>
|
||||
</bit-section-header>
|
||||
|
||||
<bit-card>
|
||||
@@ -28,7 +27,7 @@
|
||||
formControlName="selectedDeletionDatePreset"
|
||||
>
|
||||
<bit-option
|
||||
*ngFor="let o of deletionDatePresets"
|
||||
*ngFor="let o of datePresetOptions"
|
||||
[value]="o.value"
|
||||
[label]="o.name"
|
||||
></bit-option>
|
||||
|
||||
@@ -65,25 +65,11 @@ export class SendTextDetailsComponent implements OnInit {
|
||||
name: ["", [Validators.required]],
|
||||
textToShare: [""],
|
||||
hideTextByDefault: [false],
|
||||
// sendLink: [null as string],
|
||||
selectedDeletionDatePreset: [DatePreset.SevenDays, Validators.required],
|
||||
selectedDeletionDatePreset: [DatePreset.SevenDays || "", Validators.required],
|
||||
});
|
||||
|
||||
get deletionDatePresets(): DatePresetSelectOption[] {
|
||||
const defaultSelections = [
|
||||
{ name: this.i18nService.t("oneHour"), value: DatePreset.OneHour },
|
||||
{ name: this.i18nService.t("oneDay"), value: DatePreset.OneDay },
|
||||
{ name: this.i18nService.t("days", "2"), value: DatePreset.TwoDays },
|
||||
{ name: this.i18nService.t("days", "3"), value: DatePreset.ThreeDays },
|
||||
{ name: this.i18nService.t("days", "7"), value: DatePreset.SevenDays },
|
||||
{ name: this.i18nService.t("days", "14"), value: DatePreset.FourteenDays },
|
||||
{ name: this.i18nService.t("days", "30"), value: DatePreset.ThirtyDays },
|
||||
];
|
||||
if (!this.originalSendView.deletionDate) {
|
||||
return defaultSelections;
|
||||
}
|
||||
return [{ name: null, value: this.formattedDeletionDate }, ...defaultSelections];
|
||||
}
|
||||
customDeletionDateOption: DatePresetSelectOption | null = null;
|
||||
datePresetOptions: DatePresetSelectOption[] = [];
|
||||
|
||||
constructor(
|
||||
private sendFormContainer: SendFormContainer,
|
||||
@@ -95,37 +81,62 @@ export class SendTextDetailsComponent implements OnInit {
|
||||
|
||||
this.sendTextDetailsForm.valueChanges.pipe(takeUntilDestroyed()).subscribe((value) => {
|
||||
this.sendFormContainer.patchSend((send) => {
|
||||
Object.assign(send, {
|
||||
return Object.assign(send, {
|
||||
name: value.name,
|
||||
text: { text: value.textToShare, hidden: value.hideTextByDefault },
|
||||
deletionDate: new Date(this.formattedDeletionDate),
|
||||
expirationDate: new Date(this.formattedDeletionDate),
|
||||
} as SendView);
|
||||
return send;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.setupDeletionDatePresets();
|
||||
|
||||
if (this.originalSendView) {
|
||||
this.sendTextDetailsForm.patchValue({
|
||||
name: this.originalSendView.name,
|
||||
textToShare: this.originalSendView.text.text,
|
||||
hideTextByDefault: this.originalSendView.text.hidden,
|
||||
selectedDeletionDatePreset: DatePreset.SevenDays,
|
||||
selectedDeletionDatePreset: this.originalSendView.deletionDate.toString(),
|
||||
});
|
||||
|
||||
// If existing deletion date exists, calculate it once and store it
|
||||
if (this.originalSendView.deletionDate) {
|
||||
this.customDeletionDateOption = {
|
||||
name: this.datePipe.transform(this.originalSendView.deletionDate, "MM/dd/yyyy, hh:mm a"),
|
||||
value: this.originalSendView.deletionDate.toString(),
|
||||
};
|
||||
this.datePresetOptions.unshift(this.customDeletionDateOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupDeletionDatePresets() {
|
||||
const defaultSelections: DatePresetSelectOption[] = [
|
||||
{ name: this.i18nService.t("oneHour"), value: DatePreset.OneHour },
|
||||
{ name: this.i18nService.t("oneDay"), value: DatePreset.OneDay },
|
||||
{ name: this.i18nService.t("days", "2"), value: DatePreset.TwoDays },
|
||||
{ name: this.i18nService.t("days", "3"), value: DatePreset.ThreeDays },
|
||||
{ name: this.i18nService.t("days", "7"), value: DatePreset.SevenDays },
|
||||
{ name: this.i18nService.t("days", "14"), value: DatePreset.FourteenDays },
|
||||
{ name: this.i18nService.t("days", "30"), value: DatePreset.ThirtyDays },
|
||||
];
|
||||
|
||||
this.datePresetOptions = defaultSelections;
|
||||
}
|
||||
|
||||
get formattedDeletionDate(): string {
|
||||
const now = new Date();
|
||||
const milliseconds = now.setTime(
|
||||
now.getTime() +
|
||||
(this.sendTextDetailsForm.controls.selectedDeletionDatePreset.value as number) *
|
||||
60 *
|
||||
60 *
|
||||
1000,
|
||||
);
|
||||
const selectedValue = this.sendTextDetailsForm.controls.selectedDeletionDatePreset.value;
|
||||
|
||||
// If existing deletion date is selected, return it as is
|
||||
if (typeof selectedValue === "string") {
|
||||
return selectedValue;
|
||||
}
|
||||
|
||||
const milliseconds = now.setTime(now.getTime() + (selectedValue as number) * 60 * 60 * 1000);
|
||||
return new Date(milliseconds).toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +36,8 @@ class TestAddEditFormService implements SendFormService {
|
||||
decryptSend(): Promise<SendView> {
|
||||
return Promise.resolve(defaultConfig.originalSend as any);
|
||||
}
|
||||
async saveSend(send: SendView, file: File | ArrayBuffer): Promise<SendView> {
|
||||
async saveSend(send: SendView, file: File | ArrayBuffer): Promise<void> {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
return send;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,8 @@ export class DefaultSendFormService implements SendFormService {
|
||||
return await send.decrypt();
|
||||
}
|
||||
|
||||
async saveSend(
|
||||
send: SendView,
|
||||
file: File | ArrayBuffer,
|
||||
config: SendFormConfig,
|
||||
): Promise<SendView> {
|
||||
async saveSend(send: SendView, file: File | ArrayBuffer, config: SendFormConfig) {
|
||||
const sendData = await this.sendService.encrypt(send, file, send.password, null);
|
||||
const savedSend = await this.sendApiService.save(sendData);
|
||||
return await savedSend.decrypt();
|
||||
await this.sendApiService.save(sendData);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user