@occultus/article-api 0.22.0-alpha.1 → 0.23.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@occultus/article-api",
3
- "version": "0.22.0-alpha.1",
3
+ "version": "0.23.0-alpha.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://codeberg.org/TeamOccultus/StarTenonAPI"
@@ -24,15 +24,15 @@
24
24
  "license": "MIT",
25
25
  "author": "CTN Studios",
26
26
  "dependencies": {
27
- "@occultus/text-api": "0.20.0"
27
+ "@occultus/text-api": "0.23.0"
28
28
  },
29
29
  "peerDependencies": {
30
- "@occultus/core": ">=0.18.4 || <0.19.0",
31
- "@minecraft/server": ">=2.0.0",
32
- "@minecraft/server-ui": ">=2.0.0"
30
+ "@occultus/core": "1.1.0-rc.1",
31
+ "@minecraft/server": "^2.4.0",
32
+ "@minecraft/server-ui": "^2.0.0"
33
33
  },
34
34
  "devDependencies": {
35
- "typedoc": "^0.28.9"
35
+ "typedoc": "^0.28.16"
36
36
  },
37
37
  "scripts": {
38
38
  "test": "tsc"
@@ -1,16 +1,15 @@
1
1
  import { Player } from "@minecraft/server";
2
2
  import { ActionFormData } from "@minecraft/server-ui";
3
3
  import { ChapterData } from "../interface/ChapterData";
4
- import { BaseArticle } from "./Base/BaseArticle";
5
4
  import { parseText, TextProvider } from "@occultus/text-api";
6
- import { OccultusSDKError } from "@occultus/core";
5
+ import { FormLike } from "@occultus/core";
7
6
 
8
7
  /**
9
8
  * 创建一个文章
10
9
  * @category Stable
11
10
  * @since 1.0.0
12
11
  */
13
- export class Article extends BaseArticle {
12
+ export class Article extends FormLike {
14
13
  /**
15
14
  * @param id 文章ID
16
15
  * @param title 文章标题
@@ -27,7 +26,7 @@ export class Article extends BaseArticle {
27
26
  public iconPath?: string,
28
27
  public needUnlock = true
29
28
  ) {
30
- super(id, title, body, chapters);
29
+ super();
31
30
  }
32
31
  /**
33
32
  * 向玩家展示文章(文章无章节时)
@@ -35,22 +34,26 @@ export class Article extends BaseArticle {
35
34
  * @param backTo 关闭文章后返回的界面
36
35
  * @private
37
36
  */
38
- private simpleDisplay(player: Player, backTo?: BaseArticle): void {
37
+ private simpleDisplay(player: Player, backTo: FormLike[]): void {
39
38
  if (!this.checkUnlock(player)) {
40
39
  this.unlock(player);
41
40
  }
42
- const title = parseText(this.title, player);
43
- const body = parseText(this.body, player);
41
+ const [title, body] = [
42
+ parseText(this.title, player),
43
+ parseText(this.body, player)
44
+ ];
44
45
  const mainForm = new ActionFormData()
45
46
  .title(title)
46
47
  .body(body)
47
48
  .button({ translate: "gui.ok" });
48
- // @ts-ignore
49
49
  mainForm.show(player).then((response) => {
50
- if (response.selection === 0 || response.canceled) {
51
- backTo?.display(player);
50
+ if (response.canceled || response.selection === 0) {
51
+ this.quit(player, backTo);
52
52
  return;
53
53
  }
54
+ }).catch((err) => {
55
+ console.error(`[Article] Failed to display article: ${err}`);
56
+ this.quit(player, backTo as readonly FormLike[]);
54
57
  });
55
58
  }
56
59
  /**
@@ -59,48 +62,33 @@ export class Article extends BaseArticle {
59
62
  * @param backTo 关闭文章后返回的界面
60
63
  * @private
61
64
  */
62
- private chapterDisplay(player: Player, backTo?: BaseArticle): void {
65
+ private chapterDisplay(player: Player, backTo: FormLike[]): void {
63
66
  if (!this.checkUnlock(player)) {
64
67
  this.unlock(player);
65
68
  }
66
69
  const [title, body] = [
67
70
  parseText(this.title, player),
68
- parseText(this.body, player),
71
+ parseText(this.body, player)
69
72
  ];
70
73
  const contentsForm = new ActionFormData().title(title).body(body);
71
- if (!this.chapters) {
72
- throw new OccultusSDKError("Cannot find chapter data!");
73
- }
74
- this.chapters.forEach((chapter) => {
74
+ this.chapters!.forEach((chapter) => {
75
75
  const chapterTitle = parseText(chapter.title, player);
76
76
  contentsForm.button(chapterTitle, chapter.iconPath);
77
77
  });
78
- // @ts-ignore
79
78
  contentsForm.show(player).then((response) => {
80
79
  if (response.canceled || response.selection === undefined) {
81
- backTo?.display(player);
80
+ this.quit(player, backTo);
82
81
  return;
83
82
  }
84
- if (!this.chapters) {
85
- throw new OccultusSDKError("Invaild chapter data!");
86
- }
87
83
  const [chapterTitle, chapterBody] = [
88
- parseText(this.chapters[response.selection].title, player),
89
- parseText(this.chapters[response.selection].body, player),
84
+ parseText(this.chapters![response.selection].title, player),
85
+ parseText(this.chapters![response.selection].body, player)
90
86
  ];
91
-
92
- const chapterForm = new ActionFormData()
93
- .title(chapterTitle)
94
- .body(chapterBody)
95
- .button({ translate: "gui.ok" });
96
- // @ts-ignore
97
- chapterForm.show(player).then((response) => {
98
- if (response.selection === 0 || response.canceled) {
99
- // @ts-ignore
100
- contentsForm.show(player);
101
- return;
102
- }
103
- });
87
+ const chapter = new Article("temp:chapter", chapterTitle, chapterBody);
88
+ this.jumpTo(player, chapter, backTo);
89
+ }).catch((err) => {
90
+ console.error(`[Article] Failed to display article: ${err}`);
91
+ this.quit(player, backTo as readonly FormLike[]);
104
92
  });
105
93
  }
106
94
  /**
@@ -108,7 +96,7 @@ export class Article extends BaseArticle {
108
96
  * @param player 要展示文章的玩家
109
97
  * @param backTo 关闭文章后返回的界面
110
98
  */
111
- display(player: Player, backTo?: BaseArticle): void {
99
+ display(player: Player, backTo: FormLike[]): void {
112
100
  if (this.chapters) {
113
101
  this.chapterDisplay(player, backTo);
114
102
  return;
@@ -120,7 +108,9 @@ export class Article extends BaseArticle {
120
108
  * @param player
121
109
  */
122
110
  unlock(player: Player): void {
123
- player.addTag(`articleUnlock:${this.id}`);
111
+ if (this.needUnlock) {
112
+ player.addTag(`articleUnlock:${this.id}`);
113
+ }
124
114
  }
125
115
  /**
126
116
  * 检查文章是否在文章中心里解锁
@@ -2,9 +2,10 @@ import { Player } from "@minecraft/server";
2
2
  import { MessageFormData } from "@minecraft/server-ui";
3
3
  import { ArticleRegistries } from "./Base/ArticleRegistries";
4
4
  import { Article } from "./Article";
5
- import { BaseArticle } from "./Base/BaseArticle";
6
5
  import { generateContentForm } from "../lib/utils";
7
6
  import { TextProvider } from "@occultus/text-api";
7
+ import { FormLike } from "@occultus/core";
8
+ import { ReadableArticle } from "../types/ReadableArticle";
8
9
 
9
10
  /**
10
11
  * 集中显示文章的类
@@ -26,7 +27,7 @@ import { TextProvider } from "@occultus/text-api";
26
27
  * @category Stable
27
28
  * @since 1.0.0
28
29
  */
29
- export class ArticleCenter extends BaseArticle {
30
+ export class ArticleCenter extends FormLike {
30
31
  /**
31
32
  * @param id 文章中心ID
32
33
  * @param title 文章中心标题
@@ -38,72 +39,70 @@ export class ArticleCenter extends BaseArticle {
38
39
  public title: TextProvider,
39
40
  public body: TextProvider,
40
41
  public articles: Article[] | boolean,
41
- public readonly articlesManager: ArticleRegistries,
42
+ public readonly bindTo: ArticleRegistries,
42
43
  public iconPath?: string
43
44
  ) {
44
- super(id, title, body, articles);
45
+ super();
45
46
  }
46
47
  /**
47
48
  * 向玩家展示文章中心
48
49
  * @param player 要展示文章中心的玩家
49
50
  */
50
- display(player: Player): void {
51
- if (typeof this.articles === "boolean") {
52
- if (!this.articles) {
53
- this.warn(player);
54
- return;
55
- }
56
- const contentForm = generateContentForm(
57
- player,
58
- this.title,
59
- this.body,
60
- this.articlesManager.getAll()
61
- );
62
- if (!contentForm) {
63
- this.warn(player);
64
- return;
65
- }
66
- // @ts-ignore
67
- contentForm.form.show(player).then((response) => {
68
- if (response.canceled || response.selection === undefined) {
69
- return;
70
- }
71
- contentForm.list[response.selection].display(player, this);
72
- });
73
- return;
74
- }
51
+ display(player: Player, backTo: FormLike[]): void {
75
52
  const contentForm = generateContentForm(
76
53
  player,
77
54
  this.title,
78
55
  this.body,
79
- this.articles
56
+ this.getAvailableArticles()
80
57
  );
58
+
81
59
  if (!contentForm) {
82
- this.warn(player);
60
+ this.warn(player, backTo);
83
61
  return;
84
62
  }
85
- // @ts-ignore
86
- contentForm.form.show(player).then((response) => {
87
- if (response.canceled || response.selection === undefined) {
88
- return;
89
- }
90
- contentForm.list[response.selection].display(player, this);
91
- });
63
+ contentForm.form
64
+ .show(player)
65
+ .then((response) => {
66
+ if (response.canceled || response.selection === undefined) {
67
+ this.quit(player, backTo);
68
+ return;
69
+ }
70
+ this.jumpTo(player, contentForm.list[response.selection], backTo);
71
+ })
72
+ .catch((err) => {
73
+ console.error(
74
+ `[ArticleCenter] Failed to display article center: ${err}`
75
+ );
76
+ this.quit(player, backTo as readonly FormLike[]);
77
+ });
78
+ }
79
+ private getAvailableArticles(): ReadableArticle[] {
80
+ if (typeof this.articles === "boolean") {
81
+ if (!this.articles) return [];
82
+ return this.bindTo.getAll();
83
+ }
84
+ return this.articles;
92
85
  }
93
86
  /**
94
87
  * 当没有可用的文章时,向玩家显示警告
95
88
  * @param player 被显示提示的玩家
96
89
  * @private
97
90
  */
98
- private warn(player: Player): void {
91
+ private warn(player: Player, backTo: FormLike[]): void {
99
92
  const warningForm = new MessageFormData()
100
93
  .title({ translate: "article.nothing.title" })
101
94
  .body({ translate: "article.nothing.body" })
102
95
  .button1({ translate: "gui.ok" })
103
96
  .button2({ translate: "gui.close" });
104
- // @ts-ignore
105
- warningForm.show(player).then((_response) => {
106
- return;
107
- });
97
+ warningForm
98
+ .show(player)
99
+ .then((_response) => {
100
+ this.quit(player, backTo as readonly FormLike[]);
101
+ return;
102
+ })
103
+ .catch((err) => {
104
+ console.error(`[ArticleCenter] Failed to display warning form: ${err}`);
105
+ this.quit(player, backTo as readonly FormLike[]);
106
+ });
108
107
  }
109
108
  }
@@ -1,6 +1,5 @@
1
1
  import { Registries } from "@occultus/core";
2
2
  import { Article } from "../Article";
3
- import { BaseArticle } from "./BaseArticle";
4
3
  import { articleRegister } from "../../lib/utils";
5
4
  import { ArticleCenter } from "../ArticleCenter";
6
5
  import { ReadableArticle } from "../../types/ReadableArticle";
@@ -51,7 +50,7 @@ export class ArticleRegistries extends Registries {
51
50
  * @param id 文章ID
52
51
  * @return 返回找到的文章,如果没有找到则返回`undefined`
53
52
  */
54
- get(id: string): undefined | BaseArticle {
53
+ get(id: string): undefined | ReadableArticle {
55
54
  return this.registry.get(id);
56
55
  }
57
56
  /**
package/src/index.ts CHANGED
@@ -5,5 +5,4 @@ export * from "./lib/utils";
5
5
  export * from "./api/Article";
6
6
  export * from "./api/ArticleCenter";
7
7
  export * from "./api/Base/ArticleRegistries";
8
- export * from "./api/Base/BaseArticle";
9
8
  export * from "./interface/ChapterData";
@@ -1,6 +1,5 @@
1
1
  import { TextProvider } from "@occultus/text-api";
2
2
 
3
-
4
3
  /**
5
4
  * 描述文章的章节数据的接口
6
5
  */
package/src/lib/utils.ts CHANGED
@@ -1,13 +1,6 @@
1
- import {
2
- Player,
3
- RawMessage,
4
- StartupEvent,
5
- system,
6
- world,
7
- } from "@minecraft/server";
1
+ import { Player, StartupEvent } from "@minecraft/server";
8
2
  import { ActionFormData } from "@minecraft/server-ui";
9
3
  import { Article } from "../api/Article";
10
- import { BaseArticle } from "../api/Base/BaseArticle";
11
4
  import { ReadableArticle } from "../types/ReadableArticle";
12
5
  import { TextProvider, parseText } from "@occultus/text-api";
13
6
 
@@ -30,7 +23,7 @@ export function generateContentForm(
30
23
  const unlockedArticles: ReadableArticle[] = [];
31
24
  const [title, body] = [
32
25
  parseText(rawTitle, player),
33
- parseText(rawBody, player),
26
+ parseText(rawBody, player)
34
27
  ];
35
28
  const contentForm = new ActionFormData().title(title).body(body);
36
29
  articles.forEach((article) => {
@@ -55,13 +48,12 @@ export function generateContentForm(
55
48
 
56
49
  export function articleRegister(
57
50
  componentId: string,
58
- article: BaseArticle,
51
+ article: ReadableArticle,
59
52
  arg: StartupEvent
60
53
  ) {
61
54
  arg.itemComponentRegistry.registerCustomComponent(componentId, {
62
55
  onUse: (callback) => {
63
- article.display(callback.source);
64
- },
56
+ article.display(callback.source, []);
57
+ }
65
58
  });
66
59
  }
67
-
@@ -4,4 +4,4 @@ import { ArticleCenter } from "../api/ArticleCenter";
4
4
  /**
5
5
  * 所有可读文章类型
6
6
  */
7
- export type ReadableArticle = Article | ArticleCenter;
7
+ export type ReadableArticle = Article | ArticleCenter;
package/tsconfig.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "noEmit": true,
9
9
  "noEmitOnError": true,
10
10
  "target": "es2022",
11
- "lib": ["es2020", "dom"],
11
+ "lib": ["es2021", "dom"],
12
12
  "strict": true,
13
13
  "esModuleInterop": true,
14
14
  "module": "es2022",
@@ -1,26 +0,0 @@
1
- import { Player } from "@minecraft/server";
2
- import { TextProvider } from "@occultus/text-api";
3
-
4
- /**
5
- * 描述文章的抽象类
6
- */
7
- export abstract class BaseArticle {
8
- /**
9
- * @param id 文章的唯一标识符
10
- * @param title 文章的标题
11
- * @param body 文章的内容
12
- * @param data 文章的其他数据
13
- */
14
- constructor(
15
- public readonly id: string,
16
- public title: TextProvider,
17
- public body: TextProvider,
18
- public data: unknown
19
- ) {}
20
- /**
21
- * 向玩家展示文章
22
- * @param player 要展示文章的玩家
23
- * @param backTo 展示后返回的界面
24
- */
25
- abstract display(player: Player, backTo?: BaseArticle): void;
26
- }