🗑️ Clean up frontend
This commit is contained in:
parent
99f85a8b76
commit
23989f98b6
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
18
ROADMAP.md
Normal file
18
ROADMAP.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Hydrogen.Messaging 规划
|
||||||
|
|
||||||
|
- [ ] 基本聊天功能
|
||||||
|
- [ ] 发送文字消息
|
||||||
|
- [ ] 发送带有附件的消息
|
||||||
|
- [ ] 回复消息
|
||||||
|
- [ ] 转发消息
|
||||||
|
- [ ] 发送语音消息(特殊的带有附件的消息)
|
||||||
|
- [ ] 发送位置信息(带有**元数据**的信息)
|
||||||
|
- [ ] WebSocket 网关(一个 WS 链接完成所有的频道发送、接受消息功能)
|
||||||
|
- [ ] 领域聊天功能(与 Hydrogen.Interactive 的联动)
|
||||||
|
- [ ] 双方 GRPC 通信
|
||||||
|
- [ ] 在广场的领域内置聊天频道显示
|
||||||
|
- [ ] 在聊天的领域内显示广场的帖子节选
|
||||||
|
- [ ] 双方共用一个领域系统,以广场的领域为准
|
||||||
|
- [ ] 实时通讯功能
|
||||||
|
- [ ] 支持实时通知
|
||||||
|
- [ ] 支持音视频通话
|
3
go.mod
3
go.mod
@ -6,6 +6,7 @@ require (
|
|||||||
git.solsynth.dev/hydrogen/identity v0.0.0-20240320131628-6ac77f36957f
|
git.solsynth.dev/hydrogen/identity v0.0.0-20240320131628-6ac77f36957f
|
||||||
github.com/go-playground/validator/v10 v10.17.0
|
github.com/go-playground/validator/v10 v10.17.0
|
||||||
github.com/gofiber/fiber/v2 v2.52.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/golang-jwt/jwt/v5 v5.2.0
|
||||||
github.com/google/uuid v1.5.0
|
github.com/google/uuid v1.5.0
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
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/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.7.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/golang/protobuf v1.5.3 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
6
go.sum
6
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/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 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE=
|
||||||
github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
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 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
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=
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||||
|
6
pkg/embed.go
Normal file
6
pkg/embed.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package pkg
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed views/*
|
||||||
|
var FS embed.FS
|
@ -1,17 +1,18 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.solsynth.dev/hydrogen/messaging/pkg"
|
||||||
|
"github.com/gofiber/fiber/v2/middleware/favicon"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/messaging/pkg/views"
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/gofiber/fiber/v2/middleware/cache"
|
"github.com/gofiber/fiber/v2/middleware/cache"
|
||||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
"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/idempotency"
|
||||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||||
|
"github.com/gofiber/template/html/v2"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
@ -20,6 +21,8 @@ import (
|
|||||||
var A *fiber.App
|
var A *fiber.App
|
||||||
|
|
||||||
func NewServer() {
|
func NewServer() {
|
||||||
|
templates := html.NewFileSystem(http.FS(pkg.FS), ".gohtml")
|
||||||
|
|
||||||
A = fiber.New(fiber.Config{
|
A = fiber.New(fiber.Config{
|
||||||
DisableStartupMessage: true,
|
DisableStartupMessage: true,
|
||||||
EnableIPValidation: true,
|
EnableIPValidation: true,
|
||||||
@ -30,6 +33,8 @@ func NewServer() {
|
|||||||
JSONDecoder: jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal,
|
JSONDecoder: jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal,
|
||||||
BodyLimit: 50 * 1024 * 1024,
|
BodyLimit: 50 * 1024 * 1024,
|
||||||
EnablePrintRoutes: viper.GetBool("debug.print_routes"),
|
EnablePrintRoutes: viper.GetBool("debug.print_routes"),
|
||||||
|
Views: templates,
|
||||||
|
ViewsLayout: "views/index",
|
||||||
})
|
})
|
||||||
|
|
||||||
A.Use(idempotency.New())
|
A.Use(idempotency.New())
|
||||||
@ -83,15 +88,17 @@ func NewServer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
A.Use("/", cache.New(cache.Config{
|
A.Use(favicon.New(favicon.Config{
|
||||||
Expiration: 24 * time.Hour,
|
FileSystem: http.FS(pkg.FS),
|
||||||
CacheControl: true,
|
File: "views/favicon.png",
|
||||||
}), filesystem.New(filesystem.Config{
|
URL: "/favicon.png",
|
||||||
Root: http.FS(views.FS),
|
|
||||||
PathPrefix: "dist",
|
|
||||||
Index: "index.html",
|
|
||||||
NotFoundFile: "dist/index.html",
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
A.Get("/", func(c *fiber.Ctx) error {
|
||||||
|
return c.Render("views/open", fiber.Map{
|
||||||
|
"frontend": viper.GetString("frontend"),
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Listen() {
|
func Listen() {
|
||||||
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
33
pkg/views/.gitignore
vendored
33
pkg/views/.gitignore
vendored
@ -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
|
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/prettierrc",
|
|
||||||
"semi": false,
|
|
||||||
"tabWidth": 2,
|
|
||||||
"singleQuote": false,
|
|
||||||
"printWidth": 120,
|
|
||||||
"trailingComma": "none"
|
|
||||||
}
|
|
8
pkg/views/.vscode/extensions.json
vendored
8
pkg/views/.vscode/extensions.json
vendored
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"Vue.volar",
|
|
||||||
"Vue.vscode-typescript-vue-plugin",
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"esbenp.prettier-vscode"
|
|
||||||
]
|
|
||||||
}
|
|
@ -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
|
|
||||||
```
|
|
@ -1,6 +0,0 @@
|
|||||||
package views
|
|
||||||
|
|
||||||
import "embed"
|
|
||||||
|
|
||||||
//go:embed all:dist
|
|
||||||
var FS embed.FS
|
|
1
pkg/views/env.d.ts
vendored
1
pkg/views/env.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
/// <reference types="vite/client" />
|
|
BIN
pkg/views/favicon.png
Normal file
BIN
pkg/views/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
28
pkg/views/index.gohtml
Normal file
28
pkg/views/index.gohtml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png">
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<title>Hydrogen.Interactive</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-family: Roboto Mono, monospace;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{embed}}
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,13 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<link rel="icon" type="image/xml+svg" href="/favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Solarplaza</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
60
pkg/views/open.gohtml
Normal file
60
pkg/views/open.gohtml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<div class="container">
|
||||||
|
<div>
|
||||||
|
<img src="/favicon.png" width="128" height="128" alt="Icon"/>
|
||||||
|
|
||||||
|
<p class="caption text-blinking">Launching Solian... 🚀</p>
|
||||||
|
<p class="description">
|
||||||
|
Hold on a second... <br/>
|
||||||
|
We are redirecting you to our application...
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function redirect() {
|
||||||
|
window.location.href = {{ .frontend }}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => redirect(), 1850)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
margin-top: 4px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-blinking {
|
||||||
|
animation: text-blinking ease-in-out infinite 1.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin-top: 4px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes text-blinking {
|
||||||
|
0% {
|
||||||
|
opacity: 100%;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 10%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-app>
|
|
||||||
<router-view />
|
|
||||||
</v-app>
|
|
||||||
</template>
|
|
@ -1,108 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-navigation-drawer v-model="drawerOpen" color="grey-lighten-5" floating>
|
|
||||||
<div class="flex flex-col h-full">
|
|
||||||
<v-list class="border-b border-opacity-15 h-[64px]" style="border-bottom-width: thin">
|
|
||||||
<v-list-item :subtitle="username" :title="nickname">
|
|
||||||
<template #prepend>
|
|
||||||
<v-avatar icon="mdi-account-circle" :image="id.userinfo.data?.avatar" />
|
|
||||||
</template>
|
|
||||||
<template #append>
|
|
||||||
<v-menu v-if="id.userinfo.isLoggedIn">
|
|
||||||
<template #activator="{ props }">
|
|
||||||
<v-btn v-bind="props" icon="mdi-menu-down" size="small" variant="text" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<v-list density="compact">
|
|
||||||
<v-list-item
|
|
||||||
title="Solarpass"
|
|
||||||
prepend-icon="mdi-passport-biometric"
|
|
||||||
target="_blank"
|
|
||||||
:href="passportUrl"
|
|
||||||
/>
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
|
|
||||||
<v-btn v-else icon="mdi-login-variant" size="small" variant="text" :href="signinUrl" />
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
|
|
||||||
<div class="flex-grow-1">
|
|
||||||
<!-- TODO Channel list -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</v-navigation-drawer>
|
|
||||||
|
|
||||||
<v-app-bar height="64" color="primary" scroll-behavior="elevate" flat>
|
|
||||||
<div class="max-md:px-5 md:px-12 flex flex-grow-1 items-center">
|
|
||||||
<v-app-bar-nav-icon variant="text" @click.stop="toggleDrawer" />
|
|
||||||
|
|
||||||
<router-link :to="{ name: 'landing' }">
|
|
||||||
<h2 class="ml-2 text-lg font-500">Solarecho</h2>
|
|
||||||
</router-link>
|
|
||||||
|
|
||||||
<v-spacer />
|
|
||||||
|
|
||||||
<v-tooltip v-for="item in navigationMenu" :text="item.name" location="bottom">
|
|
||||||
<template #activator="{ props }">
|
|
||||||
<v-btn flat exact v-bind="props" :to="{ name: item.to }" size="small" :icon="item.icon" />
|
|
||||||
</template>
|
|
||||||
</v-tooltip>
|
|
||||||
</div>
|
|
||||||
</v-app-bar>
|
|
||||||
|
|
||||||
<v-main>
|
|
||||||
<router-view />
|
|
||||||
</v-main>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed, ref } from "vue"
|
|
||||||
import { useUserinfo } from "@/stores/userinfo"
|
|
||||||
import { useWellKnown } from "@/stores/wellKnown"
|
|
||||||
|
|
||||||
const id = useUserinfo()
|
|
||||||
const navigationMenu = [{ name: "Landing", icon: "mdi-home", to: "landing" }]
|
|
||||||
|
|
||||||
const username = computed(() => {
|
|
||||||
if (id.userinfo.isLoggedIn) {
|
|
||||||
return "@" + id.userinfo.data?.name
|
|
||||||
} else {
|
|
||||||
return "@vistor"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const nickname = computed(() => {
|
|
||||||
if (id.userinfo.isLoggedIn) {
|
|
||||||
return id.userinfo.data?.nick
|
|
||||||
} else {
|
|
||||||
return "Anonymous"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
id.readProfiles()
|
|
||||||
|
|
||||||
const meta = useWellKnown()
|
|
||||||
|
|
||||||
const signinUrl = computed(() => {
|
|
||||||
return meta.wellKnown?.components?.identity + `/auth/sign-in?redirect_uri=${encodeURIComponent(location.href)}`
|
|
||||||
})
|
|
||||||
const passportUrl = computed(() => {
|
|
||||||
return meta.wellKnown?.components?.identity
|
|
||||||
})
|
|
||||||
|
|
||||||
meta.readWellKnown()
|
|
||||||
|
|
||||||
const drawerOpen = ref(true)
|
|
||||||
|
|
||||||
function toggleDrawer() {
|
|
||||||
drawerOpen.value = !drawerOpen.value
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.editor-fab {
|
|
||||||
position: fixed !important;
|
|
||||||
bottom: 16px;
|
|
||||||
right: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -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")
|
|
@ -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
|
|
@ -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)
|
|
||||||
}
|
|
@ -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 }
|
|
||||||
})
|
|
@ -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<any>(null)
|
|
||||||
|
|
||||||
async function readWellKnown() {
|
|
||||||
const res = await request("/.well-known")
|
|
||||||
wellKnown.value = await res.json()
|
|
||||||
}
|
|
||||||
|
|
||||||
return { wellKnown, readWellKnown }
|
|
||||||
})
|
|
@ -1,3 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-container>W.I.P</v-container>
|
|
||||||
</template>
|
|
@ -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/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"files": [],
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.node.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.app.json"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -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"]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
import { defineConfig, presetAttributify, presetTypography, presetUno } from "unocss"
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
presets: [presetAttributify(), presetTypography(), presetUno({ preflight: false })]
|
|
||||||
})
|
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,6 +1,8 @@
|
|||||||
name = "Solarplaza"
|
name = "Solarplaza"
|
||||||
maintainer = "SmartSheep Studio"
|
maintainer = "SmartSheep Studio"
|
||||||
|
|
||||||
|
frontend = "https://lian.solsynth.dev"
|
||||||
|
|
||||||
bind = "0.0.0.0:8447"
|
bind = "0.0.0.0:8447"
|
||||||
domain = "feed.smartsheep.studio"
|
domain = "feed.smartsheep.studio"
|
||||||
secret = "LtTjzAGFLshwXhN4ZD4nG5KlMv1MWcsvfv03TSZYnT1VhiAnLIZFTnHUwR0XhGgi"
|
secret = "LtTjzAGFLshwXhN4ZD4nG5KlMv1MWcsvfv03TSZYnT1VhiAnLIZFTnHUwR0XhGgi"
|
||||||
|
Loading…
Reference in New Issue
Block a user