Skip to content

Commit

Permalink
Fix v2.3.2 dev problems (#194)
Browse files Browse the repository at this point in the history
* feat: add refresh accelerate uploading cache on confirm popup

* feat: add accelerate uploading tip

* feat: add default storage classes and hide accelerate uploading if private

* chore: improve accelerate uploading fee hint

* fix: download from s3 custom domain

* fix: crash when only one available storage class

* bump kodo-s3-adapter-sdk to v0.7.1
  • Loading branch information
lihsai0 authored Nov 25, 2024
1 parent 09df98a commit 63e1a24
Show file tree
Hide file tree
Showing 19 changed files with 165 additions and 82 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
"form-data": "^4.0.0",
"js-base64": "^3.4.5",
"js-md5": "^0.7.3",
"kodo-s3-adapter-sdk": "0.7.0",
"kodo-s3-adapter-sdk": "0.7.1",
"lockfile": "^1.0.4",
"lodash": "^4.17.21",
"mime": "^2.3.1",
Expand Down
3 changes: 2 additions & 1 deletion src/common/ipc-actions/download.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {NatureLanguage} from "kodo-s3-adapter-sdk/dist/uplog";
import {Domain} from "kodo-s3-adapter-sdk/dist/adapter";
import {Domain, UrlStyle} from "kodo-s3-adapter-sdk/dist/adapter";

import {ClientOptionsSerialized} from "@common/qiniu";
import {Status} from "@common/models/job/types";
Expand All @@ -24,6 +24,7 @@ export interface DownloadOptions {
bucket: string,

domain?: Domain,
urlStyle?: UrlStyle,

isOverwrite: boolean,
storageClasses: StorageClass[],
Expand Down
12 changes: 10 additions & 2 deletions src/common/models/job/download-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import fs, {constants as fsConstants, promises as fsPromises} from "fs";

import lodash from "lodash";
import {Downloader} from "kodo-s3-adapter-sdk";
import {Adapter, Domain, ObjectHeader, StorageClass} from "kodo-s3-adapter-sdk/dist/adapter";
import {Adapter, Domain, ObjectHeader, StorageClass, UrlStyle} from "kodo-s3-adapter-sdk/dist/adapter";
import {NatureLanguage} from "kodo-s3-adapter-sdk/dist/uplog";

import {ClientOptions, createQiniuClient} from "@common/qiniu";
Expand Down Expand Up @@ -36,7 +36,8 @@ interface DownloadOptions {

interface OptionalOptions extends DownloadOptions {
id: string,
domain?: Domain,
domain: Domain | undefined,
urlStyle: UrlStyle | undefined,

status: Status,
message: string,
Expand All @@ -58,6 +59,8 @@ type Options = RequiredOptions & Partial<OptionalOptions>

const DEFAULT_OPTIONS: OptionalOptions = {
id: "",
domain: undefined,
urlStyle: undefined,

multipartDownloadThreshold: 100,
multipartDownloadSize: 8,
Expand Down Expand Up @@ -86,6 +89,7 @@ type PersistInfo = {
from: RequiredOptions["from"],
backendMode: RequiredOptions["clientOptions"]["backendMode"],
domain: OptionalOptions["domain"],
urlStyle: OptionalOptions["urlStyle"],
prog: OptionalOptions["prog"],
status: Exclude<OptionalOptions["status"], Status.Waiting | Status.Running>,
message: OptionalOptions["message"],
Expand All @@ -112,6 +116,8 @@ export default class DownloadJob extends TransferJob {
): DownloadJob {
return new DownloadJob({
id,
domain: persistInfo.domain,
urlStyle: persistInfo.urlStyle,
status: persistInfo.status,
message: persistInfo.message,

Expand Down Expand Up @@ -213,6 +219,7 @@ export default class DownloadJob extends TransferJob {
to: this.options.to,
from: this.options.from,
domain: this.options.domain,
urlStyle: this.options.urlStyle,
storageClasses: this.options.storageClasses,
backendMode: this.options.clientOptions.backendMode,

Expand Down Expand Up @@ -297,6 +304,7 @@ export default class DownloadJob extends TransferJob {
this.tempFilePath,
this.options.domain,
{
urlStyle: this.options.urlStyle,
recoveredFrom: this.prog.resumable
? this.prog.loaded
: 0,
Expand Down
1 change: 1 addition & 0 deletions src/main/transfer-managers/download-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ export default class DownloadManager extends TransferManager<DownloadJob, Config
overwrite: downloadOptions.isOverwrite,
region: downloadOptions.region,
domain: downloadOptions.domain,
urlStyle: downloadOptions.urlStyle,

multipartDownloadThreshold: this.config.multipartThreshold,
multipartDownloadSize: this.config.multipartSize,
Expand Down
61 changes: 32 additions & 29 deletions src/renderer/components/forms/change-storage-class-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import StorageClass from "@common/models/storage-class";

export interface ChangeStorageClassFormData {
storageClassKodoName: string,
someInput: string,
}

interface ChangeStorageClassFormProps {
Expand Down Expand Up @@ -52,7 +51,7 @@ const ChangeStorageClassForm: React.FC<ChangeStorageClassFormProps> = ({

useEffect(() => {
reset({
storageClassKodoName: availableStorageClasses[0].kodoName ?? "Standard",
storageClassKodoName: availableStorageClasses[0]?.kodoName ?? "",
});
}, []);

Expand Down Expand Up @@ -97,33 +96,37 @@ const ChangeStorageClassForm: React.FC<ChangeStorageClassFormProps> = ({
</div>
</Form.Group>
}
<Form.Group as={Fragment} controlId="storageClassKodoName">
<Form.Label className="text-end">
{translate("forms.changeStorageClass.storageClassKodoName.label")}
</Form.Label>
<div>
{
availableStorageClasses.map(storageClass => (
<Form.Check
{...register("storageClassKodoName")}
id={`storageClassKodoName-${storageClass.kodoName}`}
key={storageClass.kodoName}
type="radio"
label={storageClass.nameI18n[currentLanguage]}
value={storageClass.kodoName}
/>
))
}
<Form.Text>
{
availableStorageClasses
.find(storageClasses =>
storageClasses.kodoName === watch("storageClassKodoName"))
?.billingI18n[currentLanguage]
}
</Form.Text>
</div>
</Form.Group>
{
!availableStorageClasses.length
? null
: <Form.Group as={Fragment} controlId="storageClassKodoName">
<Form.Label className="text-end">
{translate("forms.changeStorageClass.storageClassKodoName.label")}
</Form.Label>
<div>
{
availableStorageClasses.map(storageClass => (
<Form.Check
{...register("storageClassKodoName")}
id={`storageClassKodoName-${storageClass.kodoName}`}
key={storageClass.kodoName}
type="radio"
label={storageClass.nameI18n[currentLanguage]}
value={storageClass.kodoName}
/>
))
}
<Form.Text>
{
availableStorageClasses
.find(storageClasses =>
storageClasses.kodoName === watch("storageClassKodoName"))
?.billingI18n[currentLanguage]
}
</Form.Text>
</div>
</Form.Group>
}
</fieldset>
</Form>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ const ChangeFileStorageClass: React.FC<ModalProps & ChangeFileStorageClassProps>
const changeStorageClassFormController = useForm<ChangeStorageClassFormData>({
mode: "onChange",
defaultValues: {
storageClassKodoName: storageClasses[0]?.kodoName ?? "Standard",
storageClassKodoName: storageClasses[0]?.kodoName ?? "",
},
});

const {
watch,
handleSubmit,
formState: {
isSubmitting,
Expand Down Expand Up @@ -135,7 +136,7 @@ const ChangeFileStorageClass: React.FC<ModalProps & ChangeFileStorageClassProps>
</Modal.Body>
<Modal.Footer>
{
!memoFileItem || isSubmitSuccessful
!memoFileItem || !watch("storageClassKodoName") || isSubmitSuccessful
? null
: <Button
variant="primary"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const ChangeFilesStorageClass: React.FC<ModalProps & ChangeFilesStorageClassProp
const changeStorageClassFormController = useForm<ChangeStorageClassFormData>({
mode: "onChange",
defaultValues: {
storageClassKodoName: storageClasses[0]?.kodoName ?? "Standard",
storageClassKodoName: storageClasses[0]?.kodoName ?? "",
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,9 @@ const UploadFilesConfirm: React.FC<ModalProps & UploadFilesConfirmProps> = ({
label={translate("modals.uploadConfirm.form.accelerateUploading.hint")}
/>
{
// TODO(lihs): need to be confirmed with PM
// <Form.Text>
// {translate("modals.uploadConfirm.form.accelerateUploading.hintSecondary")}
// </Form.Text>
<Form.Text>
{translate("modals.uploadConfirm.form.accelerateUploading.hintSecondary")}
</Form.Text>
}
</div>
</Form.Group>
Expand Down Expand Up @@ -383,6 +382,7 @@ const UploadFilesConfirm: React.FC<ModalProps & UploadFilesConfirmProps> = ({
</Modal.Body>
<Modal.Footer>
{
currentUser?.endpointType === EndpointType.Public &&
onClickRefreshCanAccelerateUploading &&
<TipPopover
className="me-auto"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import {BackendMode} from "@common/qiniu"

import {useI18n} from "@renderer/modules/i18n";
import {useAuth} from "@renderer/modules/auth";
import {getContent, saveContent} from "@renderer/modules/qiniu-client";
import {getContent, saveContent, getStyleForSignature} from "@renderer/modules/qiniu-client";
import {DomainAdapter, NON_OWNED_DOMAIN} from "@renderer/modules/qiniu-client-hooks";
import {DiffView, EditorView} from "@renderer/modules/codemirror";
import {useFileOperation} from "@renderer/modules/file-operation";

import LoadingHolder from "@renderer/components/loading-holder";

Expand All @@ -34,6 +35,7 @@ const CodeContent: React.FC<CodeContentProps> = ({
}) => {
const {translate} = useI18n();
const {currentUser} = useAuth();
const {bucketPreferBackendMode: preferBackendMode} = useFileOperation();

// code mirror editor
const editorRef = useRef<Editor>();
Expand Down Expand Up @@ -76,13 +78,19 @@ const CodeContent: React.FC<CodeContentProps> = ({
endpointType: currentUser.endpointType,
preferS3Adapter: domain.apiScope === BackendMode.S3,
};
const domainToGet = domain?.name === NON_OWNED_DOMAIN.name
? undefined
: domain;
getContent(
regionId,
bucketName,
filePath,
domain.name === NON_OWNED_DOMAIN.name
? undefined
: domain,
domainToGet,
getStyleForSignature({
domain: domainToGet,
preferBackendMode,
currentEndpointType: currentUser.endpointType,
}),
opt,
)
.then(contentBuffer => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ const ChangeStorageClass: React.FC<ChangeStorageClassProps> = ({
const changeStorageClassFormController = useForm<ChangeStorageClassFormData>({
mode: "onChange",
defaultValues: {
storageClassKodoName: storageClasses[0]?.kodoName ?? "Standard",
storageClassKodoName: storageClasses[0]?.kodoName ?? "",
},
});

const {
watch,
handleSubmit,
formState: {
isSubmitting,
Expand Down Expand Up @@ -123,7 +124,7 @@ const ChangeStorageClass: React.FC<ChangeStorageClassProps> = ({
onSubmit={handleSubmitChangeStorageClass}
/>
{
!SubmitButtonPortal || isSubmitSuccessful
!SubmitButtonPortal || !watch("storageClassKodoName") || isSubmitSuccessful
? null
: <SubmitButtonPortal>
<Button
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/modules/i18n/lang/ja-jp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ const dict: Dictionary = {
accelerateUploading: {
label: "アップロードを加速する:",
hint: "(今回だけ)",
hintSecondary: "開いた後、アクセラレーションドメインを優先してアップロードします;アクセラレーションドメインを使用する場合、追加料金が発生します。",
hintSecondary: "開いた後、アクセラレーションドメインを優先してアップロードします;アクセラレーションドメインを使用する場合、追加通信料金が発生します。",
},
storageClassKodoName: {
label: "保管タイプ:",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/modules/i18n/lang/zh-cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ const dict: Dictionary = {
accelerateUploading: {
label: "加速上传:",
hint: "(仅本次)",
hintSecondary: "开启后,优先通过加速域名上传;当使用加速域名上传时,产生额外费用。",
hintSecondary: "开启后,优先通过加速域名上传;当使用加速域名上传时,产生传输加速费用。",
},
storageClassKodoName: {
label: "存储类型:",
Expand Down
24 changes: 22 additions & 2 deletions src/renderer/modules/qiniu-client-hooks/use-load-regions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {useEffect, useState} from "react";
import {Region} from "kodo-s3-adapter-sdk";
import {RegionStorageClass} from "kodo-s3-adapter-sdk/dist/region";
import {toast} from "react-hot-toast";

import * as LocalLogger from "@renderer/modules/local-logger";
Expand All @@ -12,6 +13,20 @@ interface LoadRegionsState {
regions: Region[],
}

const DEFAULT_REGION_STORAGE_CLASSES: RegionStorageClass[] = [
{
fileType: 0,
kodoName: "Standard",
s3Name: "STANDARD",
billingI18n: {},
nameI18n: {
en_US: "Standard",
ja_JP: "標準",
zh_CN: "标准存储",
},
},
];

export default function useLoadRegions({
user,
shouldAutoReload,
Expand Down Expand Up @@ -63,8 +78,7 @@ export default function useLoadRegions({
} else {
try {
regions = regionsFromEndpointConfig.map(r => {
const storageClasses = regionsFromFetch
.find(i => i.s3Id === r.identifier)?.storageClasses ?? []
const storageClasses = regionsFromFetch.find(i => i.s3Id === r.identifier)?.storageClasses;
const result = new Region(
r.identifier,
r.identifier,
Expand All @@ -90,6 +104,12 @@ export default function useLoadRegions({
}
}
} finally {
// set default storage classes
regions?.forEach(r => {
if (!r.storageClasses.length) {
r.storageClasses.push(...DEFAULT_REGION_STORAGE_CLASSES.map(sc => ({...sc})));
}
});
setLoadRegionsState({
loading: false,
regions: regions || [],
Expand Down
12 changes: 9 additions & 3 deletions src/renderer/modules/qiniu-client/common.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ import * as MockAuth from "@common/qiniu/_mock-helpers_/auth";

import { RegionService } from "kodo-s3-adapter-sdk/dist/region_service";

jest.mock("kodo-s3-adapter-sdk/dist/region_service", () => ({
jest.mock("kodo-s3-adapter-sdk/dist/region_service", () => {
class MockedRegionService extends jest.fn() {
static clearCache = jest.fn();
clearCache = jest.fn();
}
return {
__esModule: true,
RegionService: jest.fn().mockReturnValue({ clearCache: () => {} }),
}));
RegionService: MockedRegionService,
}
});

import { Kodo as KodoAdapter } from "kodo-s3-adapter-sdk/dist/kodo";
import { S3 as S3Adapter } from "kodo-s3-adapter-sdk/dist/s3";
Expand Down
Loading

0 comments on commit 63e1a24

Please sign in to comment.