Skip to content

Commit f4b76b7

Browse files
committed
Merge branch 'develop'
# Conflicts: # main.js
2 parents bdbdbea + 0b98d18 commit f4b76b7

20 files changed

+1461
-1011
lines changed

main.js

Lines changed: 1076 additions & 863 deletions
Large diffs are not rendered by default.

src/abstract-wp-client.ts

Lines changed: 68 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { App, Modal, Notice } from 'obsidian';
1+
import { Modal, Notice } from 'obsidian';
22
import WordpressPlugin from './main';
3-
import { WpLoginModal } from './wp-login-modal';
3+
import { openLoginModal } from './wp-login-modal';
44
import {
55
WordPressAuthParams,
66
WordPressClient,
@@ -9,15 +9,17 @@ import {
99
WordPressPostParams,
1010
WordPressPublishParams
1111
} from './wp-client';
12-
import { WpPublishModal } from './wp-publish-modal';
12+
import { openPublishModal } from './wp-publish-modal';
1313
import { Term } from './wp-api';
14-
import { ERROR_NOTICE_TIMEOUT } from './consts';
14+
import { ERROR_NOTICE_TIMEOUT, WP_DEFAULT_PROFILE_NAME } from './consts';
1515
import matter from 'gray-matter';
1616
import yaml from 'js-yaml';
17-
import { isPromiseFulfilledResult, openWithBrowser, SafeAny } from './utils';
18-
import { PostPublishedModal } from './post-published-modal';
17+
import { doClientPublish, isPromiseFulfilledResult, openWithBrowser, SafeAny } from './utils';
18+
import { openPostPublishedModal } from './post-published-modal';
1919
import { WpProfile } from './wp-profile';
2020
import { AppState } from './app-state';
21+
import { ConfirmCode, openConfirmModal } from './confirm-modal';
22+
import { isNil } from 'lodash-es';
2123

2224

2325
const matterOptions = {
@@ -36,7 +38,6 @@ const matterOptions = {
3638
export abstract class AbstractWordPressClient implements WordPressClient {
3739

3840
protected constructor(
39-
protected readonly app: App,
4041
protected readonly plugin: WordpressPlugin,
4142
protected readonly profile: WpProfile
4243
) { }
@@ -75,19 +76,52 @@ export abstract class AbstractWordPressClient implements WordPressClient {
7576
});
7677
}
7778

78-
const { activeEditor } = this.app.workspace;
79+
const { activeEditor } = app.workspace;
7980
if (activeEditor && activeEditor.file) {
80-
const publishToWordPress = async (
81-
username: string | null,
82-
password: string | null,
83-
loginModal?: Modal
84-
) => {
81+
(async () => {
82+
let username = null;
83+
let password = null;
84+
let loginModal;
85+
if (this.openLoginModal()) {
86+
if (this.profile.username && this.profile.password) {
87+
// saved username and password found
88+
username = this.profile.username;
89+
password = this.profile.password;
90+
} else {
91+
const loginModalReturns = await openLoginModal(this.plugin, this.profile);
92+
username = loginModalReturns.username;
93+
password = loginModalReturns.password;
94+
loginModal = loginModalReturns.loginModal;
95+
}
96+
}
97+
// start publishing...
8598
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
8699
const noteTitle = activeEditor.file!.basename;
87100
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
88-
const rawContent = await this.app.vault.read(activeEditor.file!);
101+
const rawContent = await app.vault.read(activeEditor.file!);
89102
const { content, data: matterData } = matter(rawContent, matterOptions);
90103

104+
if (!isNil(matterData.profileName)
105+
&& matterData.profileName.length > 0
106+
&& matterData.profileName !== this.profile.name
107+
) {
108+
const confirm = await openConfirmModal({
109+
message: this.plugin.i18n.t('error_profileNotMatch'),
110+
cancelText: this.plugin.i18n.t('profileNotMatch_useOld', {
111+
profileName: matterData.profileName
112+
}),
113+
confirmText: this.plugin.i18n.t('profileNotMatch_useNew', {
114+
profileName: this.profile.name
115+
})
116+
}, this.plugin);
117+
if (confirm.code === ConfirmCode.Cancel) {
118+
doClientPublish(this.plugin, matterData.profileName);
119+
return Promise.resolve();
120+
} else {
121+
delete matterData.postId;
122+
matterData.categories = this.profile.lastSelectedCategories ?? [ 1 ];
123+
}
124+
}
91125
const validateUserResult = await this.validateUser({ username, password });
92126
if (validateUserResult.code === WordPressClientReturnCode.OK) {
93127
if (defaultPostParams) {
@@ -106,53 +140,22 @@ export abstract class AbstractWordPressClient implements WordPressClient {
106140
password
107141
});
108142
const selectedCategories = matterData.categories as number[] ?? this.profile.lastSelectedCategories;
109-
new WpPublishModal(
110-
this.app,
111-
this.plugin,
112-
categories,
113-
selectedCategories,
114-
async (postParams, publishModal) => {
115-
const params = this.readFromFrontMatter(noteTitle, matterData, postParams);
116-
params.content = content;
117-
const result = await this.doPublish({
118-
username,
119-
password,
120-
postParams: params,
121-
matterData
122-
}, loginModal, publishModal);
123-
resolve(result);
124-
}
125-
).open();
143+
const { postParams, publishModal } = await openPublishModal(this.plugin, categories, selectedCategories);
144+
const params = this.readFromFrontMatter(noteTitle, matterData, postParams);
145+
params.content = content;
146+
const result = await this.doPublish({
147+
username,
148+
password,
149+
postParams: params,
150+
matterData
151+
}, loginModal, publishModal);
152+
resolve(result);
126153
}
127154
} else {
128155
const invalidUsernameOrPassword = this.plugin.i18n.t('error_invalidUser');
129156
new Notice(invalidUsernameOrPassword, ERROR_NOTICE_TIMEOUT);
130157
}
131-
};
132-
133-
if (this.openLoginModal()) {
134-
if (this.profile.username && this.profile.password) {
135-
// saved username and password found
136-
publishToWordPress(this.profile.username, this.profile.password).then(() => {
137-
// make compiler happy
138-
});
139-
} else {
140-
new WpLoginModal(
141-
this.app,
142-
this.plugin,
143-
this.profile,
144-
(username, password, loginModal) => {
145-
publishToWordPress(username, password, loginModal).then(() => {
146-
// make compiler happy
147-
});
148-
}
149-
).open();
150-
}
151-
} else {
152-
publishToWordPress(null, null).then(() => {
153-
// make compiler happy
154-
});
155-
}
158+
})();
156159
} else {
157160
const error = 'There is no editor or file found. Nothing will be published.';
158161
console.warn(error);
@@ -204,6 +207,7 @@ export abstract class AbstractWordPressClient implements WordPressClient {
204207
const postId = (result.data as SafeAny).postId;
205208
if (postId) {
206209
// save post id to front-matter
210+
matterData.profileName = this.profile.name;
207211
matterData.postId = postId;
208212
matterData.categories = postParams.categories;
209213
const modified = matter.stringify(postParams.content, matterData, matterOptions);
@@ -215,13 +219,13 @@ export abstract class AbstractWordPressClient implements WordPressClient {
215219
}
216220

217221
if (this.plugin.settings.showWordPressEditConfirm) {
218-
new PostPublishedModal(this.app, this.plugin, (modal: Modal) => {
219-
openWithBrowser(`${this.profile.endpoint}/wp-admin/post.php`, {
220-
action: 'edit',
221-
post: postId
222+
openPostPublishedModal(this.plugin)
223+
.then(() => {
224+
openWithBrowser(`${this.profile.endpoint}/wp-admin/post.php`, {
225+
action: 'edit',
226+
post: postId
227+
});
222228
});
223-
modal.close();
224-
}).open();
225229
}
226230
}
227231
}
@@ -260,6 +264,7 @@ export abstract class AbstractWordPressClient implements WordPressClient {
260264
if (matterData.postId) {
261265
postParams.postId = matterData.postId;
262266
}
267+
postParams.profileName = matterData.profileName ?? WP_DEFAULT_PROFILE_NAME;
263268
if (matterData.categories) {
264269
postParams.categories = matterData.categories as number[] ?? this.profile.lastSelectedCategories;
265270
}
@@ -270,7 +275,7 @@ export abstract class AbstractWordPressClient implements WordPressClient {
270275
}
271276

272277
private updateFrontMatter(value: string): void {
273-
const { activeEditor } = this.app.workspace;
278+
const { activeEditor } = app.workspace;
274279
if (activeEditor) {
275280
const editor = activeEditor.editor;
276281
if (editor) {

src/confirm-modal.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { Modal, Setting } from 'obsidian';
2+
import WordpressPlugin from './main';
3+
import { TranslateKey } from './i18n';
4+
5+
6+
export enum ConfirmCode {
7+
Cancel,
8+
Confirm
9+
}
10+
11+
export interface ConfirmModalMessages {
12+
message: string;
13+
cancelText?: string;
14+
confirmText?: string;
15+
}
16+
17+
export function openConfirmModal(
18+
messages: ConfirmModalMessages,
19+
plugin: WordpressPlugin
20+
): Promise<{ code: ConfirmCode }> {
21+
return new Promise((resolve, reject) => {
22+
const modal = new ConfirmModal(
23+
messages,
24+
plugin,
25+
(code, modal) => {
26+
resolve({
27+
code
28+
});
29+
modal.close();
30+
});
31+
modal.open();
32+
});
33+
}
34+
35+
/**
36+
* Confirm modal.
37+
*/
38+
export class ConfirmModal extends Modal {
39+
40+
constructor(
41+
private readonly messages: ConfirmModalMessages,
42+
private readonly plugin: WordpressPlugin,
43+
private readonly onAction: (code: ConfirmCode, modal: Modal) => void
44+
) {
45+
super(app);
46+
}
47+
48+
onOpen() {
49+
const t = (key: TranslateKey, vars?: Record<string, string>): string => {
50+
return this.plugin.i18n.t(key, vars);
51+
};
52+
53+
const { contentEl } = this;
54+
55+
contentEl.createEl('h1', { text: t('confirmModal_title') });
56+
57+
new Setting(contentEl)
58+
.setName(this.messages.message);
59+
60+
new Setting(contentEl)
61+
.addButton(button => button
62+
.setButtonText(this.messages.cancelText ?? t('confirmModal_cancel'))
63+
.onClick(() => {
64+
this.onAction(ConfirmCode.Cancel, this);
65+
})
66+
)
67+
.addButton(button => button
68+
.setButtonText(this.messages.confirmText ?? t('confirmModal_confirm'))
69+
.setCta()
70+
.onClick(() => {
71+
this.onAction(ConfirmCode.Confirm, this);
72+
})
73+
);
74+
}
75+
76+
onClose() {
77+
const { contentEl } = this;
78+
contentEl.empty();
79+
}
80+
81+
}

src/consts.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export const WP_OAUTH2_VALIDATE_TOKEN_ENDPOINT = 'https://public-api.wordpress.c
88
export const WP_OAUTH2_URL_ACTION = 'wordpress-plugin-oauth';
99
export const WP_OAUTH2_REDIRECT_URI = `obsidian://${WP_OAUTH2_URL_ACTION}`;
1010

11+
export const WP_DEFAULT_PROFILE_NAME = 'Default';
12+
1113
export const enum EventType {
1214
OAUTH2_TOKEN_GOT = 'OAUTH2_TOKEN_GOT'
1315
}

src/i18n/en.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,23 @@
55
"error_noPassword": "No password",
66
"error_noProfile": "No profile, please add one at least",
77
"error_noProfileName": "No profile name",
8+
"error_noSuchProfile": "No profile with name <%= profileName %>",
89
"error_invalidUrl": "Invalid URL",
910
"error_invalidUser": "Invalid username or password",
1011
"error_publishFailed": "Post published failed!\n<%= code %>: <%= message %>",
1112
"error_wpComAuthFailed": "WordPress authorize failed!\n<%= error %>: <%= desc %>",
1213
"error_invalidWpComToken": "Invalid wordpress.com token",
1314
"error_cannotParseResponse": "Cannot parse WordPress server response.",
1415
"error_noDefaultProfile": "No default profile found.",
16+
"error_profileNotMatch": "WordPress profile not match. Which one do you want to use?",
1517
"message_publishSuccessfully": "Post published successfully!",
1618
"message_wpComTokenValidated": "Wordpress.com token validated successfully!",
1719
"ribbon_iconTitle": "WordPress Publish",
1820
"command_publish": "Publish current note",
1921
"command_publishWithDefault": "Publish current note with default options",
22+
"confirmModal_title": "Confirmation",
23+
"confirmModal_cancel": "Cancel",
24+
"confirmModal_confirm": "Confirm",
2025
"settings_title": "WordPress Publish",
2126
"settings_profiles": "Profiles",
2227
"settings_profilesDesc": "Manage WordPress profiles.",
@@ -98,5 +103,7 @@
98103
"profileModal_setDefault": "Set Default",
99104
"profilesChooserModal_title": "Profiles",
100105
"profilesChooserModal_pickOne": "Click to pick one profile to publish.",
101-
"profiles_default": "Default Profile"
106+
"profiles_default": "Default Profile",
107+
"profileNotMatch_useOld": "Use \"<%= profileName %>\" in the note",
108+
"profileNotMatch_useNew": "Create a new post using \"<%= profileName %>\""
102109
}

src/i18n/zh-cn.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,23 @@
55
"error_noPassword": "没有设置密码",
66
"error_noProfile": "没有账号,请至少添加一个 WordPress 账号",
77
"error_noProfileName": "没有设置账号名",
8+
"error_noSuchProfile": "账号 <%= profileName %> 不存在",
89
"error_invalidUrl": "URL 格式错误",
910
"error_invalidUser": "用户名或密码错误",
1011
"error_publishFailed": "文章发布失败\n<%= code %>: <%= message %>",
1112
"error_wpComAuthFailed": "WordPress 认证失败!\n<%= error %>: <%= desc %>",
1213
"error_invalidWpComToken": "非法的 wordpress.com 令牌",
1314
"error_cannotParseResponse": "无法识别 WordPress 服务器的响应",
1415
"error_noDefaultProfile": "无法找到默认账号",
16+
"error_profileNotMatch": "WordPress 账号不匹配,使用哪一个账号?",
1517
"message_publishSuccessfully": "文章发布成功",
1618
"message_wpComTokenValidated": "Wordpress.com 令牌验证通过",
1719
"ribbon_iconTitle": "发布到 WordPress",
1820
"command_publish": "发布当前笔记",
1921
"command_publishWithDefault": "使用默认参数发布当前笔记",
22+
"confirmModal_title": "需要确认",
23+
"confirmModal_cancel": "取消",
24+
"confirmModal_confirm": "确认",
2025
"settings_title": "WordPress 发布插件",
2126
"settings_profiles": "WordPress 账户",
2227
"settings_profilesDesc": "管理 WordPress 账户",
@@ -98,5 +103,7 @@
98103
"profileModal_setDefault": "设为默认",
99104
"profilesChooserModal_title": "WordPress 账户",
100105
"profilesChooserModal_pickOne": "点击选择一个需要发布到的 WordPress 账户",
101-
"profiles_default": "默认账户"
106+
"profiles_default": "默认账户",
107+
"profileNotMatch_useOld": "使用笔记中的 \"<%= profileName %>\"",
108+
"profileNotMatch_useNew": "使用 \"<%= profileName %>\" 创建新的文章"
102109
}

0 commit comments

Comments
 (0)