Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
ylc395 committed Oct 17, 2021
1 parent ffc43e0 commit 8bbb41f
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 120 deletions.
15 changes: 11 additions & 4 deletions src/domain/model/Publishing.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { isError } from 'lodash';

export interface Github {
userName: string;
email: string;
Expand All @@ -23,10 +25,15 @@ export interface GeneratingProgress {
}

export enum PublishResults {
SUCCESS = 'SUCCESS',
GITHUB_INFO_ERROR = 'GITHUB_INFO_ERROR',
TERMINATED = 'TERMINATED',
FAIL = 'FAIL',
Success = 'SUCCESS',
Terminated = 'TERMINATED',
Fail = 'FAIL',
}

export class PublishError extends Error {
constructor(readonly type: PublishResults.Terminated | PublishResults.Fail, e?: unknown) {
super(isError(e) ? e.message : e ? String(e) : undefined);
}
}

export interface PublishingProgress {
Expand Down
42 changes: 21 additions & 21 deletions src/domain/service/PublishService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import {
initialGeneratingProgress,
initialPublishProgress,
PublishResults,
PublishError,
DEFAULT_GITHUB,
} from '../model/Publishing';
import { AppService, FORBIDDEN } from './AppService';
import { isEmpty, isError, noop, omit, pick, some } from 'lodash';
import { isEmpty, noop, omit, pick, some } from 'lodash';

export enum GeneratorEvents {
PageGenerated = 'pageGenerated',
Expand All @@ -32,10 +33,11 @@ export enum LocalRepoStatus {
Initializing,
}

const MESSAGES: Record<string, string | undefined> = {
[PublishResults.GITHUB_INFO_ERROR]:
'Something wrong with your Github information(including token). Please check if you provided the correct information.',
[PublishResults.TERMINATED]: 'Publishing terminated.',
const PUBLISH_RESULT_MESSAGE: Record<PublishResults, string> = {
[PublishResults.Terminated]: 'Publishing terminated.',
[PublishResults.Fail]:
'This is an unexpected error, you can retry, and report it as a Github issue',
[PublishResults.Success]: '',
};

export interface Git extends EventEmitter<GitEvents> {
Expand All @@ -61,7 +63,7 @@ export class PublishService {
private readonly generator = container.resolve(generatorToken);
private readonly git = container.resolve(gitClientToken);
private files: string[] = [];
private localRepoStatus: LocalRepoStatus = LocalRepoStatus.Initializing;
readonly localRepoStatus: Ref<LocalRepoStatus> = ref(LocalRepoStatus.Initializing);
readonly githubInfo: Ref<Github | null> = ref(null);
readonly isGenerating = ref(false);
readonly isPublishing = ref(false);
Expand Down Expand Up @@ -97,9 +99,9 @@ export class PublishService {
}

private handleLocalRepoStatusChanged(status: LocalRepoStatus) {
this.localRepoStatus = status;
this.localRepoStatus.value = status;

if (this.localRepoStatus === LocalRepoStatus.Initializing) {
if (status === LocalRepoStatus.Initializing) {
this.refreshPublishingProgress({
phase: 'Local repository initializing...',
message: '',
Expand Down Expand Up @@ -170,36 +172,34 @@ export class PublishService {
this.git.terminate();
}

async publish(initGit = false) {
async publish(isRetry = false) {
if (this.isPublishing.value) {
return;
}

if (!this.isGithubInfoValid.value) {
throw new Error('invalid github info');
}
const initGit_ = initGit || this.localRepoStatus === LocalRepoStatus.Fail;

if (initGit_) {
const needToInit = isRetry || this.localRepoStatus.value === LocalRepoStatus.Fail;

if (needToInit) {
this.refreshPublishingProgress();
}

this.isPublishing.value = true;

try {
await this.git.push(this.files, initGit_);
this.publishingProgress.result = PublishResults.SUCCESS;
await this.git.push(this.files, needToInit);
this.publishingProgress.result = PublishResults.Success;
} catch (error) {
if (!isError(error)) {
if (error instanceof PublishError) {
const message = `${error.message || ''} ${PUBLISH_RESULT_MESSAGE[error.type]}`.trim();
this.publishingProgress.result = error.type;
this.publishingProgress.message = message;
} else {
throw error;
}

const { message } = error;

this.publishingProgress.result =
message in MESSAGES ? (message as PublishResults) : PublishResults.FAIL;

this.publishingProgress.message = MESSAGES[message] || message;
} finally {
this.isPublishing.value = false;
}
Expand Down
91 changes: 44 additions & 47 deletions src/driver/git/webviewApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ import {
pickBy,
isTypedArray,
isObjectLike,
isError,
cloneDeep,
} from 'lodash';
import { wrap, Remote, releaseProxy, expose } from 'comlink';
import fs from 'driver/fs/webviewApi';
import type { FsWorkerCallRequest, FsWorkerCallResponse } from 'driver/fs/type';
import { gitClientToken, GitEvents, LocalRepoStatus } from 'domain/service/PublishService';
import { Github, PublishResults } from 'domain/model/Publishing';
import { Github, PublishError, PublishResults } from 'domain/model/Publishing';
import { joplinToken } from 'domain/service/AppService';
import type { GitEventHandler, WorkerGit } from './type';

Expand Down Expand Up @@ -43,7 +42,7 @@ class Git extends EventEmitter<GitEvents> {
private worker?: Worker;
private workerGit?: Remote<WorkerGit>;
private initRepoPromise?: Promise<void>;
private stopInitRepo?: (reason: unknown) => void;
private rejectInitRepoPromise?: (reason?: unknown) => void;
private isPushing = false;

async init(githubInfo: Github, dir: string) {
Expand Down Expand Up @@ -82,17 +81,17 @@ class Git extends EventEmitter<GitEvents> {
}

this.initRepoPromise = new Promise((resolve, reject) => {
const reject_ = (e: unknown) => {
reject(e);
const reject_ = (e?: unknown) => {
this.emit(GitEvents.LocalRepoStatusChanged, LocalRepoStatus.Fail);
reject(new PublishError(PublishResults.Fail, e));
};

const resolve_ = () => {
resolve();
this.emit(GitEvents.LocalRepoStatusChanged, LocalRepoStatus.Ready);
};

this.stopInitRepo = reject_;
this.rejectInitRepoPromise = reject_;
this.emit(GitEvents.LocalRepoStatusChanged, LocalRepoStatus.Initializing);
workerGit
.initRepo({
Expand All @@ -110,20 +109,14 @@ class Git extends EventEmitter<GitEvents> {
return this.initRepoPromise;
}

private initWorker(triggerTerminate = false) {
private initWorker() {
if (!this.installDir) {
throw new Error('no install dir');
}

this.worker?.terminate();

if (triggerTerminate) {
this.emit(GitEvents.Terminated);
}

this.workerGit?.[releaseProxy]();
this.stopInitRepo?.('Repo Initialization has been terminated');
this.stopInitRepo = void 0;
this.rejectInitRepoPromise?.();

this.worker = new Worker(`${this.installDir}/driver/git/webWorker.js`);
this.workerGit = wrap(this.worker);
Expand All @@ -150,50 +143,53 @@ class Git extends EventEmitter<GitEvents> {
throw new Error('pushing!');
}

if (!this.workerGit) {
throw new Error('worker init failed');
}

if (!this.githubInfo || !this.dir || !this.gitdir) {
throw new Error('git info is not prepared');
if (!this.initRepoPromise) {
throw new Error('no initRepoPromise');
}

this.isPushing = true;
const terminatePromise = new Promise<never>((resolve, reject) => {
this.once(GitEvents.Terminated, () => reject(Error(PublishResults.TERMINATED)));
});

try {
if (needToInit) {
this.initRepo();
}
await Promise.race([this.initRepoPromise, terminatePromise]);
} catch (error) {
this.isPushing = false;

if (isError(error) && (error.message.includes('401') || error.message.includes('404'))) {
throw Error(PublishResults.GITHUB_INFO_ERROR);
} else {
throw error;
}
if (needToInit) {
this.initRepo();
}

try {
await Promise.race([
this.workerGit.publish({
files,
githubInfo: this.githubInfo,
gitInfo: {
dir: this.dir,
gitdir: this.gitdir,
url: Git.getRemoteUrl(this.githubInfo.userName, this.githubInfo.repositoryName),
remote: Git.remote,
},
this.initRepoPromise.then(() => {
if (!this.workerGit) {
throw new Error('worker init failed');
}

if (!this.githubInfo || !this.dir || !this.gitdir) {
throw new Error('git info is not prepared');
}

return this.workerGit.publish({
files,
githubInfo: this.githubInfo,
gitInfo: {
dir: this.dir,
gitdir: this.gitdir,
url: Git.getRemoteUrl(this.githubInfo.userName, this.githubInfo.repositoryName),
remote: Git.remote,
},
});
}),
new Promise<never>((resolve, reject) => {
this.once(GitEvents.Terminated, () =>
reject(new PublishError(PublishResults.Terminated)),
);
}),
terminatePromise,
]);
} catch (error) {
if (error instanceof PublishError) {
throw error;
}

throw new PublishError(PublishResults.Fail, error);
} finally {
this.isPushing = false;
this.off(GitEvents.Terminated);
}
}

Expand Down Expand Up @@ -232,7 +228,8 @@ class Git extends EventEmitter<GitEvents> {
};

terminate() {
this.initWorker(true);
this.emit(GitEvents.Terminated);
this.initWorker();
}
}

Expand Down
99 changes: 51 additions & 48 deletions src/driver/webview/app/Publisher/PublishingModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,53 +46,56 @@ export default defineComponent({
<Button @click="stopPublishing">Stop</Button>
</div>
</template>
<Result
v-if="progress.result"
class="py-3 px-4"
:status="progress.result !== PublishResults.SUCCESS ? 'error' : 'success'"
:title="
progress.result !== PublishResults.SUCCESS ? 'Fail to publish' : 'Published Successfully'
"
>
<template #subTitle>
<div v-if="progress.result !== PublishResults.SUCCESS" class="text-left">
<p>{{ progress.message }}</p>
<p>
<template v-if="progress.result === PublishResults.FAIL"
>This is an unexpected error, you can retry, and report it as a Github issue.
</template>
Or if you are a Git user, you can use Git manually to continue publishing.
<a
href="https://github.com/ylc395/joplin-plugin-pages-publisher/wiki/How-to-use-git-manually"
target="_blank"
>See this docs for details</a
>
</p>
</div>
<div v-else-if="githubInfo">
Please Check:
<ul class="text-gray-400 text-left list-disc">
<li class="mt-2">
https://github.com/{{ githubInfo.userName }}/{{
githubInfo.repositoryName || `${githubInfo.userName}.github.io`
}}{{ githubInfo.branch ? `/tree/${githubInfo.branch}` : '' }}
</li>
<li v-if="githubInfo.cname">https://{{ githubInfo.cname }}</li>
<li v-if="isDefaultRepository && !githubInfo.cname">
https://{{ githubInfo.userName }}.github.io
</li>
</ul>
</div>
</template>
<template #extra>
<Button v-if="progress.result" @click="reset">Confirm</Button>
<Button
v-if="[PublishResults.FAIL, PublishResults.GITHUB_INFO_ERROR].includes(progress.result)"
type="primary"
@click="publish(true)"
>Retry</Button
>
</template>
</Result>
<div v-if="progress.result" class="py-3 px-4">
<Result
v-if="progress.result === PublishResults.Success"
status="success"
title="Published Successfully"
>
<template #subTitle>
<div v-if="githubInfo">
Please Check:
<ul class="text-gray-400 text-left list-disc">
<li class="mt-2">
https://github.com/{{ githubInfo.userName }}/{{
githubInfo.repositoryName || `${githubInfo.userName}.github.io`
}}{{ githubInfo.branch ? `/tree/${githubInfo.branch}` : '' }}
</li>
<li v-if="githubInfo.cname">https://{{ githubInfo.cname }}</li>
<li v-if="isDefaultRepository && !githubInfo.cname">
https://{{ githubInfo.userName }}.github.io
</li>
</ul>
</div>
</template>
<template #extra>
<Button @click="reset">Confirm</Button>
</template>
</Result>
<Result v-else status="error" title="Fail to publish">
<template #subTitle>
<div :class="{ 'text-left': progress.result === PublishResults.Fail }">
<p>{{ progress.message }}</p>
<p v-if="progress.result === PublishResults.Fail">
Or if you are a Git user, you can use Git manually to continue publishing.
<a
href="https://github.com/ylc395/joplin-plugin-pages-publisher/wiki/How-to-use-git-manually"
target="_blank"
>See this docs for details</a
>
</p>
</div>
</template>
<template #extra>
<Button @click="reset">Confirm</Button>
<Button
v-if="progress.result === PublishResults.Fail"
type="primary"
@click="publish(true)"
>Retry</Button
>
</template>
</Result>
</div>
</Modal>
</template>

0 comments on commit 8bbb41f

Please sign in to comment.