diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..f3fedb4 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,18 @@ +# Hydrogen.Messaging 规划 + +- [ ] 基本聊天功能 + - [ ] 发送文字消息 + - [ ] 发送带有附件的消息 + - [ ] 回复消息 + - [ ] 转发消息 + - [ ] 发送语音消息(特殊的带有附件的消息) + - [ ] 发送位置信息(带有**元数据**的信息) + - [ ] WebSocket 网关(一个 WS 链接完成所有的频道发送、接受消息功能) +- [ ] 领域聊天功能(与 Hydrogen.Interactive 的联动) + - [ ] 双方 GRPC 通信 + - [ ] 在广场的领域内置聊天频道显示 + - [ ] 在聊天的领域内显示广场的帖子节选 + - [ ] 双方共用一个领域系统,以广场的领域为准 +- [ ] 实时通讯功能 + - [ ] 支持实时通知 + - [ ] 支持音视频通话 \ No newline at end of file diff --git a/go.mod b/go.mod index 66cbd9d..3fa14be 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( git.solsynth.dev/hydrogen/identity v0.0.0-20240320131628-6ac77f36957f github.com/go-playground/validator/v10 v10.17.0 github.com/gofiber/fiber/v2 v2.52.0 + github.com/gofiber/template/html/v2 v2.1.1 github.com/golang-jwt/jwt/v5 v5.2.0 github.com/google/uuid v1.5.0 github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible @@ -27,6 +28,8 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-sql-driver/mysql v1.7.1 // indirect + github.com/gofiber/template v1.8.3 // indirect + github.com/gofiber/utils v1.1.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect diff --git a/go.sum b/go.sum index 0232238..614710a 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,12 @@ github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE= github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= +github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc= +github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8= +github.com/gofiber/template/html/v2 v2.1.1 h1:QEy3O3EBkvwDthy5bXVGUseOyO6ldJoiDxlF4+MJiV8= +github.com/gofiber/template/html/v2 v2.1.1/go.mod h1:2G0GHHOUx70C1LDncoBpe4T6maQbNa4x1CVNFW0wju0= +github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM= +github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= diff --git a/pkg/embed.go b/pkg/embed.go new file mode 100644 index 0000000..38dd3ff --- /dev/null +++ b/pkg/embed.go @@ -0,0 +1,6 @@ +package pkg + +import "embed" + +//go:embed views/* +var FS embed.FS diff --git a/pkg/server/startup.go b/pkg/server/startup.go index b31b456..04f2b0a 100644 --- a/pkg/server/startup.go +++ b/pkg/server/startup.go @@ -1,17 +1,18 @@ package server import ( + "git.solsynth.dev/hydrogen/messaging/pkg" + "github.com/gofiber/fiber/v2/middleware/favicon" "net/http" "strings" "time" - "git.solsynth.dev/hydrogen/messaging/pkg/views" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cache" "github.com/gofiber/fiber/v2/middleware/cors" - "github.com/gofiber/fiber/v2/middleware/filesystem" "github.com/gofiber/fiber/v2/middleware/idempotency" "github.com/gofiber/fiber/v2/middleware/logger" + "github.com/gofiber/template/html/v2" jsoniter "github.com/json-iterator/go" "github.com/rs/zerolog/log" "github.com/spf13/viper" @@ -20,6 +21,8 @@ import ( var A *fiber.App func NewServer() { + templates := html.NewFileSystem(http.FS(pkg.FS), ".gohtml") + A = fiber.New(fiber.Config{ DisableStartupMessage: true, EnableIPValidation: true, @@ -30,6 +33,8 @@ func NewServer() { JSONDecoder: jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal, BodyLimit: 50 * 1024 * 1024, EnablePrintRoutes: viper.GetBool("debug.print_routes"), + Views: templates, + ViewsLayout: "views/index", }) A.Use(idempotency.New()) @@ -83,15 +88,17 @@ func NewServer() { } } - A.Use("/", cache.New(cache.Config{ - Expiration: 24 * time.Hour, - CacheControl: true, - }), filesystem.New(filesystem.Config{ - Root: http.FS(views.FS), - PathPrefix: "dist", - Index: "index.html", - NotFoundFile: "dist/index.html", + A.Use(favicon.New(favicon.Config{ + FileSystem: http.FS(pkg.FS), + File: "views/favicon.png", + URL: "/favicon.png", })) + + A.Get("/", func(c *fiber.Ctx) error { + return c.Render("views/open", fiber.Map{ + "frontend": viper.GetString("frontend"), + }) + }) } func Listen() { diff --git a/pkg/views/.eslintrc.cjs b/pkg/views/.eslintrc.cjs deleted file mode 100644 index 94744c3..0000000 --- a/pkg/views/.eslintrc.cjs +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-env node */ -require("@rushstack/eslint-patch/modern-module-resolution") - -module.exports = { - root: true, - extends: [ - "plugin:vue/vue3-essential", - "eslint:recommended", - "@vue/eslint-config-typescript", - "@vue/eslint-config-prettier/skip-formatting" - ], - parserOptions: { - ecmaVersion: "latest" - }, - rules: { - "vue/multi-word-component-names": "off", - "vue/valid-v-for": "off", - "vue/require-v-for-key": "off" - } -} diff --git a/pkg/views/.gitignore b/pkg/views/.gitignore deleted file mode 100644 index a2e7c9e..0000000 --- a/pkg/views/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -.DS_Store -dist -dist-ssr -coverage -*.local - -/cypress/videos/ -/cypress/screenshots/ - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? - -*.tsbuildinfo - -*.lockb -*.lock \ No newline at end of file diff --git a/pkg/views/.prettierrc.json b/pkg/views/.prettierrc.json deleted file mode 100644 index 88cdad7..0000000 --- a/pkg/views/.prettierrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/prettierrc", - "semi": false, - "tabWidth": 2, - "singleQuote": false, - "printWidth": 120, - "trailingComma": "none" -} diff --git a/pkg/views/.vscode/extensions.json b/pkg/views/.vscode/extensions.json deleted file mode 100644 index 009a534..0000000 --- a/pkg/views/.vscode/extensions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "recommendations": [ - "Vue.volar", - "Vue.vscode-typescript-vue-plugin", - "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode" - ] -} diff --git a/pkg/views/README.md b/pkg/views/README.md deleted file mode 100644 index a164f21..0000000 --- a/pkg/views/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# views - -This template should help get you started developing with Vue 3 in Vite. - -## Recommended IDE Setup - -[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). - -## Type Support for `.vue` Imports in TS - -TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. - -If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: - -1. Disable the built-in TypeScript Extension - 1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette - 2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` -2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. - -## Customize configuration - -See [Vite Configuration Reference](https://vitejs.dev/config/). - -## Project Setup - -```sh -npm install -``` - -### Compile and Hot-Reload for Development - -```sh -npm run dev -``` - -### Type-Check, Compile and Minify for Production - -```sh -npm run build -``` - -### Lint with [ESLint](https://eslint.org/) - -```sh -npm run lint -``` diff --git a/pkg/views/embed.go b/pkg/views/embed.go deleted file mode 100644 index bc04fa4..0000000 --- a/pkg/views/embed.go +++ /dev/null @@ -1,6 +0,0 @@ -package views - -import "embed" - -//go:embed all:dist -var FS embed.FS diff --git a/pkg/views/env.d.ts b/pkg/views/env.d.ts deleted file mode 100644 index 11f02fe..0000000 --- a/pkg/views/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/pkg/views/favicon.png b/pkg/views/favicon.png new file mode 100644 index 0000000..112fb34 Binary files /dev/null and b/pkg/views/favicon.png differ diff --git a/pkg/views/index.gohtml b/pkg/views/index.gohtml new file mode 100644 index 0000000..68f74eb --- /dev/null +++ b/pkg/views/index.gohtml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + Hydrogen.Interactive + + + + +{{embed}} + + \ No newline at end of file diff --git a/pkg/views/index.html b/pkg/views/index.html deleted file mode 100644 index 87c2281..0000000 --- a/pkg/views/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Solarplaza - - -
- - - diff --git a/pkg/views/open.gohtml b/pkg/views/open.gohtml new file mode 100644 index 0000000..1cf5416 --- /dev/null +++ b/pkg/views/open.gohtml @@ -0,0 +1,60 @@ +
+
+ Icon + +

Launching Solian... 🚀

+

+ Hold on a second...
+ We are redirecting you to our application... +

+
+
+ + + + \ No newline at end of file diff --git a/pkg/views/package.json b/pkg/views/package.json deleted file mode 100644 index f466f41..0000000 --- a/pkg/views/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "views", - "version": "0.0.0", - "private": true, - "type": "module", - "scripts": { - "dev": "vite", - "build": "run-p type-check \"build-only {@}\" --", - "preview": "vite preview", - "build-only": "vite build", - "type-check": "vue-tsc --build --force", - "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", - "format": "prettier --write src/" - }, - "dependencies": { - "@fontsource/roboto": "^5.0.8", - "@mdi/font": "^7.4.47", - "@unocss/reset": "^0.58.5", - "dompurify": "^3.0.9", - "marked": "^12.0.0", - "pinia": "^2.1.7", - "universal-cookie": "^7.1.0", - "unocss": "^0.58.5", - "vue": "^3.4.15", - "vue-easy-lightbox": "next", - "vue-router": "^4.2.5", - "vuetify": "^3.5.7" - }, - "devDependencies": { - "@rushstack/eslint-patch": "^1.3.3", - "@tsconfig/node20": "^20.1.2", - "@types/dompurify": "^3.0.5", - "@types/node": "^20.11.10", - "@unocss/preset-typography": "^0.58.5", - "@vitejs/plugin-vue": "^5.0.3", - "@vitejs/plugin-vue-jsx": "^3.1.0", - "@vue/eslint-config-prettier": "^8.0.0", - "@vue/eslint-config-typescript": "^12.0.0", - "@vue/tsconfig": "^0.5.1", - "eslint": "^8.49.0", - "eslint-plugin-vue": "^9.17.0", - "npm-run-all2": "^6.1.1", - "prettier": "^3.0.3", - "typescript": "~5.3.0", - "vite": "^5.0.11", - "vue-tsc": "^1.8.27" - } -} diff --git a/pkg/views/src/assets/utils.css b/pkg/views/src/assets/utils.css deleted file mode 100644 index 840e4ee..0000000 --- a/pkg/views/src/assets/utils.css +++ /dev/null @@ -1,15 +0,0 @@ -html, -body, -#app, -.v-application { - overflow: auto !important; - font-family: "Roboto Sans", ui-sans-serif, system-ui, sans-serif; -} - -.no-scrollbar { - scrollbar-width: none; -} - -.no-scrollbar::-webkit-scrollbar { - width: 0; -} diff --git a/pkg/views/src/index.vue b/pkg/views/src/index.vue deleted file mode 100644 index 4f21c35..0000000 --- a/pkg/views/src/index.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/pkg/views/src/layouts/master.vue b/pkg/views/src/layouts/master.vue deleted file mode 100644 index 7673d74..0000000 --- a/pkg/views/src/layouts/master.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - - - diff --git a/pkg/views/src/main.ts b/pkg/views/src/main.ts deleted file mode 100644 index 233d23b..0000000 --- a/pkg/views/src/main.ts +++ /dev/null @@ -1,54 +0,0 @@ -import "virtual:uno.css" - -import "./assets/utils.css" - -import { createApp } from "vue" -import { createPinia } from "pinia" - -import "vuetify/styles" -import { createVuetify } from "vuetify" -import { md3 } from "vuetify/blueprints" -import * as components from "vuetify/components" -import * as labsComponents from "vuetify/labs/components" -import * as directives from "vuetify/directives" - -import "@mdi/font/css/materialdesignicons.min.css" -import "@fontsource/roboto/latin.css" -import "@unocss/reset/tailwind.css" - -import index from "./index.vue" -import router from "./router" - -const app = createApp(index) - -app.use( - createVuetify({ - directives, - components: { - ...components, - ...labsComponents - }, - blueprint: md3, - theme: { - defaultTheme: "original", - themes: { - original: { - colors: { - primary: "#4a5099", - secondary: "#2196f3", - accent: "#009688", - error: "#f44336", - warning: "#ff9800", - info: "#03a9f4", - success: "#4caf50" - } - } - } - } - }) -) - -app.use(createPinia()) -app.use(router) - -app.mount("#app") diff --git a/pkg/views/src/router/index.ts b/pkg/views/src/router/index.ts deleted file mode 100644 index 52728d8..0000000 --- a/pkg/views/src/router/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { createRouter, createWebHistory } from "vue-router" -import MasterLayout from "@/layouts/master.vue" - -const router = createRouter({ - history: createWebHistory(import.meta.env.BASE_URL), - routes: [ - { - path: "/", - component: MasterLayout, - children: [ - { - path: "/", - name: "landing", - component: () => import("@/views/landing.vue") - }, - ] - } - ] -}) - -export default router diff --git a/pkg/views/src/scripts/request.ts b/pkg/views/src/scripts/request.ts deleted file mode 100644 index 5540ff2..0000000 --- a/pkg/views/src/scripts/request.ts +++ /dev/null @@ -1,10 +0,0 @@ -declare global { - interface Window { - __LAUNCHPAD_TARGET__?: string - } -} - -export async function request(input: string, init?: RequestInit) { - const prefix = window.__LAUNCHPAD_TARGET__ ?? "" - return await fetch(prefix + input, init) -} diff --git a/pkg/views/src/stores/userinfo.ts b/pkg/views/src/stores/userinfo.ts deleted file mode 100644 index 386a857..0000000 --- a/pkg/views/src/stores/userinfo.ts +++ /dev/null @@ -1,56 +0,0 @@ -import Cookie from "universal-cookie" -import { defineStore } from "pinia" -import { ref } from "vue" -import { request } from "@/scripts/request" - -export interface Userinfo { - isReady: boolean - isLoggedIn: boolean - displayName: string - data: any -} - -const defaultUserinfo: Userinfo = { - isReady: false, - isLoggedIn: false, - displayName: "Citizen", - data: null -} - -export function getAtk(): string { - return new Cookie().get("identity_auth_key") -} - -export function checkLoggedIn(): boolean { - return new Cookie().get("identity_auth_key") -} - -export const useUserinfo = defineStore("userinfo", () => { - const userinfo = ref(defaultUserinfo) - const isReady = ref(false) - - async function readProfiles() { - if (!checkLoggedIn()) { - isReady.value = true - } - - const res = await request("/api/users/me", { - headers: { Authorization: `Bearer ${getAtk()}` } - }) - - if (res.status !== 200) { - return - } - - const data = await res.json() - - userinfo.value = { - isReady: true, - isLoggedIn: true, - displayName: data["nick"], - data: data - } - } - - return { userinfo, isReady, readProfiles } -}) diff --git a/pkg/views/src/stores/wellKnown.ts b/pkg/views/src/stores/wellKnown.ts deleted file mode 100644 index 498f838..0000000 --- a/pkg/views/src/stores/wellKnown.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { request } from "@/scripts/request" -import { defineStore } from "pinia" -import { ref } from "vue" - -export const useWellKnown = defineStore("well-known", () => { - const wellKnown = ref(null) - - async function readWellKnown() { - const res = await request("/.well-known") - wellKnown.value = await res.json() - } - - return { wellKnown, readWellKnown } -}) diff --git a/pkg/views/src/views/landing.vue b/pkg/views/src/views/landing.vue deleted file mode 100644 index 21b9463..0000000 --- a/pkg/views/src/views/landing.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/pkg/views/tsconfig.app.json b/pkg/views/tsconfig.app.json deleted file mode 100644 index 292c91d..0000000 --- a/pkg/views/tsconfig.app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "@vue/tsconfig/tsconfig.dom.json", - "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], - "exclude": ["src/**/__tests__/*"], - "compilerOptions": { - "composite": true, - "allowJs": true, - "checkJs": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - } - } -} diff --git a/pkg/views/tsconfig.json b/pkg/views/tsconfig.json deleted file mode 100644 index 66b5e57..0000000 --- a/pkg/views/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.app.json" - } - ] -} diff --git a/pkg/views/tsconfig.node.json b/pkg/views/tsconfig.node.json deleted file mode 100644 index 2c669ee..0000000 --- a/pkg/views/tsconfig.node.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "@tsconfig/node20/tsconfig.json", - "include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "nightwatch.conf.*", "playwright.config.*"], - "compilerOptions": { - "composite": true, - "noEmit": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - - "module": "ESNext", - "moduleResolution": "Bundler", - "types": ["node"] - } -} diff --git a/pkg/views/uno.config.ts b/pkg/views/uno.config.ts deleted file mode 100644 index d0bf10d..0000000 --- a/pkg/views/uno.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { defineConfig, presetAttributify, presetTypography, presetUno } from "unocss" - -export default defineConfig({ - presets: [presetAttributify(), presetTypography(), presetUno({ preflight: false })] -}) diff --git a/pkg/views/vite.config.ts b/pkg/views/vite.config.ts deleted file mode 100644 index d86038d..0000000 --- a/pkg/views/vite.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { fileURLToPath, URL } from "node:url" - -import { defineConfig } from "vite" -import vue from "@vitejs/plugin-vue" -import vueJsx from "@vitejs/plugin-vue-jsx" -import unocss from "unocss/vite" - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [vue(), vueJsx(), unocss()], - resolve: { - alias: { - "@": fileURLToPath(new URL("./src", import.meta.url)) - } - }, - server: { - proxy: { - "/.well-known": "http://localhost:8447", - "/api": "http://localhost:8447" - } - } -}) diff --git a/settings.toml b/settings.toml index ae5bd2e..7e63461 100644 --- a/settings.toml +++ b/settings.toml @@ -1,6 +1,8 @@ name = "Solarplaza" maintainer = "SmartSheep Studio" +frontend = "https://lian.solsynth.dev" + bind = "0.0.0.0:8447" domain = "feed.smartsheep.studio" secret = "LtTjzAGFLshwXhN4ZD4nG5KlMv1MWcsvfv03TSZYnT1VhiAnLIZFTnHUwR0XhGgi"