Skip to content

Commit

Permalink
feat: completed the initial version design for the moments feature. (#2)
Browse files Browse the repository at this point in the history
#### What type of PR is this?
/kind feature

#### Which issue(s) this PR fixes:

Fixes halo-dev/halo#2930

#### What this PR does / why we need it:
瞬间插件初版功能设计。
Console 端:
1. 增加了“瞬间”管理页面。用户将可以通过 Console 创建瞬间。
2. 支持瞬间内容添加图片,视频。
3. 支持使用富文本编辑器。

主题端:
1. 新增了 `/moments` 及 `/moments/page/{page}` 路由,需使用 `moments.html` 页面,分页数量在插件设置中进行修改。
2. 增加了 `momentFinder`。

#### how to test it?

1. 测试 Console 端瞬间基本逻辑是否正确。包括
    a. 新增一个瞬间内容,查看是否能够刷新列表且内容是否正确,图片或视频是否存在,可见性是否支持。
    b. 双击已经存在的瞬间内容,查看是否能够修改,且修改后的数据是否正确。
    c. 删除一个瞬间内容,查看能否被成功删除。
    d. 使用搜索框,查看对应的瞬间内容能否被搜索到。
    e. 查看分页数据是否符合逻辑。
2. 测试主题端 `moments.html` 是否存在 `moments` 数据,以及分页是否正常。
3. 测试主题端 `momentFinder` 是否正确读取到数据,分页是否正常。

可测试插件包:[plugin-moments-1.0.0-plain.jar.zip](https://github.com/halo-sigs/plugin-moments/files/11110429/plugin-moments-1.0.0-plain.jar.zip)


#### Does this PR introduce a user-facing change?

```release-note
增加瞬间插件,为主题端提供 `/moments` 路由
```
  • Loading branch information
LIlGG authored Apr 3, 2023
1 parent 7303ff5 commit f92627b
Show file tree
Hide file tree
Showing 54 changed files with 5,947 additions and 837 deletions.
252 changes: 251 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,253 @@
# plugin-moments

Halo 2.0 的瞬间管理插件(WIP)。
Halo 2.0 的瞬间管理插件, 支持在 Console 进行管理以及为主题端提供 `/moments` 页面路由。

## 使用方式

1.[Releases](https://github.com/halo-sigs/plugin-moments/releases) 下载最新的 JAR 文件。
2. 在 Halo 后台的插件管理上传 JAR 文件进行安装。

> 需要注意的是,此插件需要主题提供模板(moments.html)才能访问 `/moments`
## 主题适配

目前此插件为主题端提供了 `/moments` 路由,模板为 `moments.html`,也提供了 [Finder API](https://docs.halo.run/developer-guide/theme/finder-apis),可以将瞬间列表渲染到任何地方。

## 开发环境

```bash
git clone [email protected]:halo-sigs/plugin-moments.git

# 或者当你 fork 之后

git clone [email protected]:{your_github_id}/plugin-moments.git
```

```bash
cd path/to/plugin-moments
```

```bash
# macOS / Linux
./gradlew pnpmInstall

# Windows
./gradlew.bat pnpmInstall
```

```bash
# macOS / Linux
./gradlew build

# Windows
./gradlew.bat build
```

修改 Halo 配置文件:

```yaml
halo:
plugin:
runtime-mode: development
classes-directories:
- "build/classes"
- "build/resources"
lib-directories:
- "libs"
fixedPluginPath:
- "/path/to/plugin-moments"
```
### 模板变量
#### 路由信息
- 模板路径:/templates/moments.html
- 访问路径:/moments
#### 变量
moments
##### 变量类型
[#UrlContextListResult\<MomentVo>](#urlcontextlistresult-momentvo)
##### 示例
```html
<div>
<ul>
<li th:each="moment : ${moments.items}" th:with="content=${moment.spec.content}">
<div th:if="${not #strings.isEmpty(content.html)}" th:utext="${content.html}"></div>
<th:block th:if="${not #lists.isEmpty(content.medium)}" th:each="momentItem : ${content.medium}">
<img th:if="${momentItem.type.name == 'PHOTO'}" th:src="${momentItem.url}" />
<video th:if="${momentItem.type.name == 'VIDEO'}" th:src="${momentItem.url}"></video>
</th:block>
</li>
</ul>
<div th:if="${moments.hasPrevious() || moments.hasNext()}">
<a th:href="@{${moments.prevUrl}}">
<span>上一页</span>
</a>
<span th:text="${moments.page}"></span>
<a th:href="@{${moments.nextUrl}}">
<span>下一页</span>
</a>
</div>
</div>
```

### Finder API

#### listAll()

##### 描述

获取全部瞬间内容。

##### 参数


##### 返回值

List<[#MomentVo](#momentvo)>

##### 示例

```html
<ul>
<li th:each="moment : ${momentFinder.listAll()}" th:with="content = ${moment.spec.content}">
<div th:if="${not #strings.isEmpty(content.html)}" th:utext="${content.html}"></div>
<th:block th:if="${not #lists.isEmpty(content.medium)}" th:each="momentItem : ${content.medium}">
<img th:if="${momentItem.type.name == 'PHOTO'}" th:src="${momentItem.url}" />
<video th:if="${momentItem.type.name == 'VIDEO'}" th:src="${momentItem.url}"></video>
</th:block>
</li>
</ul>
```

#### list(page, size)

##### 描述

根据分页参数获取瞬间列表。

##### 参数

1. `page: int` - 分页页码,从 1 开始
2. `size: int` - 分页条数

##### 返回值

[ListResult\<MomentVo>](#listresult-momentvo)

##### 示例

```html
<th:block th:with="moments = ${momentFinder.list(1, 10)}">
<ul>
<li th:each="moment : ${moments.items}" th:with="content = ${moment.spec.content}">
<div th:if="${not #strings.isEmpty(content.html)}" th:utext="${content.html}"></div>
<th:block th:if="${not #lists.isEmpty(content.medium)}" th:each="momentItem : ${content.medium}">
<img th:if="${momentItem.type.name == 'PHOTO'}" th:src="${momentItem.url}" />
<video th:if="${momentItem.type.name == 'VIDEO'}" th:src="${momentItem.url}"></video>
</th:block>
</li>
</ul>
<div>
<span th:text="${moments.page}"></span>
</div>
</th:block>
```

### 类型定义

#### MomentVo

```json
{
"metadata": {
"name": "string", // 唯一标识
"labels": {
"additionalProp1": "string"
},
"annotations": {
"additionalProp1": "string"
},
"creationTimestamp": "2022-11-20T13:06:38.512Z", // 创建时间
},
"spec": {
"content": {
"raw": "string", // 原始内容,一般用于编辑器使用
"html": "string", // HTML 内容,用于主题端进行最终渲染的内容
"medium": [ // 媒体内容
{
"type": "#MomentMediaType", // 类型
"url": "string", // 链接
"originType": "string", // 原始类型,例如:image/jpeg
}
]
},
"releaseTime": "string", // 发布时间
"visible": "PUBLIC", // 可见性
"owner": "string", // 所属用户
},
"owner": {
"name": "string", // 用户名
"avatar": "string", // 头像
"bio": "string", // 描述
"displayName": "string", // 显示名称
},
"stats": {
"upvote": 0, // 点赞数
"totalComment": 0, // 评论数
"approvedComment": 0, // 审核通过的评论数
}
}
```

#### MomentMediaType

```java
enum Target {
PHOTO, // 图片
VIDEO, // 视频
POST; // 文章
}
```

#### ListResult<MomentVo>

```json
{
"page": 0, // 当前页码
"size": 0, // 每页条数
"total": 0, // 总条数
"items": "List<#MomentVo>", // 瞬间列表数据
"first": true, // 是否为第一页
"last": true, // 是否为最后一页
"hasNext": true, // 是否有下一页
"hasPrevious": true, // 是否有上一页
"totalPages": 0 // 总页数
}
```

#### UrlContextListResult<MomentVo>

```json
{
"page": 0, // 当前页码
"size": 0, // 每页条数
"total": 0, // 总条数
"items": "List<#MomentVo>", // 瞬间列表数据
"first": true, // 是否为第一页
"last": true, // 是否为最后一页
"hasNext": true, // 是否有下一页
"hasPrevious": true, // 是否有上一页
"totalPages": 0, // 总页数
"prevUrl": "string", // 上一页链接
"nextUrl": "string" // 下一页链接
}
```
38 changes: 13 additions & 25 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,47 +1,34 @@
plugins {
id 'org.springframework.boot' version '3.0.0-M3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id "com.github.node-gradle.node" version "3.3.0"
id "io.github.guqing.plugin-development" version "0.0.5-SNAPSHOT"
id "io.freefair.lombok" version "8.0.0-rc2"
id "io.github.guqing.plugin-development" version "0.0.6-SNAPSHOT"
id 'java'
}

group 'run.halo.moments'
version '0.0.1-SNAPSHOT'
version '1.0.0-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_17

repositories {
maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots' }
maven { url 'https://repo.spring.io/milestone' }
mavenCentral()
}

bootJar {
enabled = false
maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots' }
}

jar {
enabled = true
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest.attributes('Plugin-Version': "${project.version}",)
from {
configurations.runtimeClasspath.collect {
it.isDirectory() ? it : zipTree(it)
}
into('lib') {
from configurations.runtimeClasspath
}
}

dependencies {
compileOnly "io.swagger.core.v3:swagger-core-jakarta:2.2.0"
compileOnly "org.pf4j:pf4j:3.6.0"
compileOnly files("lib/halo-2.0.0-SNAPSHOT-plain.jar")
compileOnly 'org.springframework.boot:spring-boot-starter-webflux'

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation platform('run.halo.tools.platform:plugin:2.5.0-SNAPSHOT')
compileOnly 'run.halo.app:api'

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
testImplementation 'run.halo.app:api'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
Expand All @@ -58,8 +45,9 @@ task pnpmInstall(type: NpxTask) {
}

task buildFrontend(type: NpxTask) {
command = "pnpm@7"
args = ["build"]
command = 'pnpm@7'
args = ['build']
dependsOn("pnpmInstall")
}

build {
Expand Down
1 change: 1 addition & 0 deletions console/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_API_URL=
14 changes: 7 additions & 7 deletions console/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
require("@rushstack/eslint-patch/modern-module-resolution");

module.exports = {
"root": true,
"extends": [
root: true,
extends: [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/eslint-config-typescript/recommended",
"@vue/eslint-config-prettier"
"@vue/eslint-config-prettier",
],
"env": {
"vue/setup-compiler-macros": true
}
}
env: {
"vue/setup-compiler-macros": true,
},
};
Loading

0 comments on commit f92627b

Please sign in to comment.