diff --git a/pkg/models/posts.go b/pkg/models/posts.go index 12d9a36..cb8eedb 100644 --- a/pkg/models/posts.go +++ b/pkg/models/posts.go @@ -5,10 +5,8 @@ import "time" type Post struct { BaseModel - Alias string `json:"alias" gorm:"uniqueIndex"` - Title string `json:"title"` Content string `json:"content"` - Tags []Tag `json:"tags" gorm:"many2many:post_tags"` + Hashtags []Tag `json:"tags" gorm:"many2many:post_tags"` Categories []Category `json:"categories" gorm:"many2many:post_categories"` Attachments []Attachment `json:"attachments"` LikedAccounts []PostLike `json:"liked_accounts"` diff --git a/pkg/server/creators_api.go b/pkg/server/creators_api.go index 21f53fb..9d72759 100644 --- a/pkg/server/creators_api.go +++ b/pkg/server/creators_api.go @@ -12,13 +12,13 @@ import ( func getOwnPost(c *fiber.Ctx) error { user := c.Locals("principal").(models.Account) - id := c.Params("postId") + id, _ := c.ParamsInt("postId", 0) take := c.QueryInt("take", 0) offset := c.QueryInt("offset", 0) tx := database.C.Where(&models.Post{ - Alias: id, - AuthorID: user.ID, + BaseModel: models.BaseModel{ID: uint(id)}, + AuthorID: user.ID, }) post, err := services.GetPost(tx) diff --git a/pkg/server/posts_api.go b/pkg/server/posts_api.go index 76bc14a..48d9ef6 100644 --- a/pkg/server/posts_api.go +++ b/pkg/server/posts_api.go @@ -13,12 +13,12 @@ import ( ) func getPost(c *fiber.Ctx) error { - id := c.Params("postId") + id, _ := c.ParamsInt("postId", 0) take := c.QueryInt("take", 0) offset := c.QueryInt("offset", 0) tx := database.C.Where(&models.Post{ - Alias: id, + BaseModel: models.BaseModel{ID: uint(id)}, }).Where("published_at <= ? OR published_at IS NULL", time.Now()) post, err := services.GetPost(tx) @@ -162,8 +162,6 @@ func createPost(c *fiber.Ctx) error { post, err := services.NewPost( user, realm, - data.Alias, - data.Title, data.Content, data.Attachments, data.Categories, @@ -207,8 +205,6 @@ func editPost(c *fiber.Ctx) error { post, err := services.EditPost( post, - data.Alias, - data.Title, data.Content, data.PublishedAt, data.Categories, diff --git a/pkg/server/startup.go b/pkg/server/startup.go index 1fdb923..398a432 100644 --- a/pkg/server/startup.go +++ b/pkg/server/startup.go @@ -5,7 +5,7 @@ import ( "strings" "time" - "code.smartsheep.studio/hydrogen/identity/pkg/views" + "code.smartsheep.studio/hydrogen/interactive/pkg/views" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cache" "github.com/gofiber/fiber/v2/middleware/cors" diff --git a/pkg/services/posts.go b/pkg/services/posts.go index c02ce17..84df779 100644 --- a/pkg/services/posts.go +++ b/pkg/services/posts.go @@ -20,7 +20,7 @@ func PreloadRelatedPost(tx *gorm.DB) *gorm.DB { Preload("Author"). Preload("Attachments"). Preload("Categories"). - Preload("Tags"). + Preload("Hashtags"). Preload("RepostTo"). Preload("ReplyTo"). Preload("RepostTo.Author"). @@ -29,8 +29,8 @@ func PreloadRelatedPost(tx *gorm.DB) *gorm.DB { Preload("ReplyTo.Attachments"). Preload("RepostTo.Categories"). Preload("ReplyTo.Categories"). - Preload("RepostTo.Tags"). - Preload("ReplyTo.Tags") + Preload("RepostTo.Hashtags"). + Preload("ReplyTo.Hashtags") } func FilterPostWithCategory(tx *gorm.DB, alias string) *gorm.DB { @@ -161,7 +161,7 @@ WHERE t.id IN ?`, prefix, prefix, prefix, prefix, prefix), postIds).Scan(&reactI func NewPost( user models.Account, realm *models.Realm, - alias, title, content string, + content string, attachments []models.Attachment, categories []models.Category, tags []models.Tag, @@ -202,11 +202,9 @@ func NewPost( } post = models.Post{ - Alias: alias, - Title: title, Content: content, Attachments: attachments, - Tags: tags, + Hashtags: tags, Categories: categories, AuthorID: user.ID, RealmID: realmId, @@ -225,7 +223,7 @@ func NewPost( BaseModel: models.BaseModel{ID: *post.ReplyID}, }).Preload("Author").First(&op).Error; err == nil { if op.Author.ID != user.ID { - postUrl := fmt.Sprintf("https://%s/posts/%s", viper.GetString("domain"), post.Alias) + postUrl := fmt.Sprintf("https://%s/posts/%d", viper.GetString("domain"), post.ID) err := NotifyAccount( op.Author, fmt.Sprintf("%s replied you", user.Name), @@ -252,7 +250,7 @@ func NewPost( }) for _, account := range accounts { - postUrl := fmt.Sprintf("https://%s/posts/%s", viper.GetString("domain"), post.Alias) + postUrl := fmt.Sprintf("https://%s/posts/%d", viper.GetString("domain"), post.ID) err := NotifyAccount( account, fmt.Sprintf("%s just posted a post", user.Name), @@ -270,7 +268,7 @@ func NewPost( func EditPost( post models.Post, - alias, title, content string, + content string, publishedAt *time.Time, categories []models.Category, tags []models.Tag, @@ -294,11 +292,9 @@ func EditPost( publishedAt = lo.ToPtr(time.Now()) } - post.Alias = alias - post.Title = title post.Content = content post.PublishedAt = *publishedAt - post.Tags = tags + post.Hashtags = tags post.Categories = categories post.Attachments = attachments diff --git a/pkg/views/bun.lockb b/pkg/views/bun.lockb index a5a3806..5a1b84d 100755 Binary files a/pkg/views/bun.lockb and b/pkg/views/bun.lockb differ diff --git a/pkg/views/embed.go b/pkg/views/embed.go new file mode 100644 index 0000000..bc04fa4 --- /dev/null +++ b/pkg/views/embed.go @@ -0,0 +1,6 @@ +package views + +import "embed" + +//go:embed all:dist +var FS embed.FS diff --git a/pkg/views/index.html b/pkg/views/index.html index f2b3b63..d6488dc 100644 --- a/pkg/views/index.html +++ b/pkg/views/index.html @@ -2,7 +2,7 @@ - + Goatplaza diff --git a/pkg/views/package.json b/pkg/views/package.json index 69649f9..8a00dc9 100644 --- a/pkg/views/package.json +++ b/pkg/views/package.json @@ -13,9 +13,11 @@ "format": "prettier --write src/" }, "dependencies": { + "@fontsource/roboto": "^5.0.8", "@mdi/font": "^7.4.47", "@unocss/reset": "^0.58.5", "pinia": "^2.1.7", + "universal-cookie": "^7.1.0", "unocss": "^0.58.5", "vue": "^3.4.15", "vue-router": "^4.2.5", diff --git a/pkg/views/public/favicon.svg b/pkg/views/public/favicon.svg new file mode 100755 index 0000000..d42a1a1 --- /dev/null +++ b/pkg/views/public/favicon.svg @@ -0,0 +1,21 @@ + + SmartSheep Logo + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pkg/views/src/assets/utils.css b/pkg/views/src/assets/utils.css new file mode 100644 index 0000000..52b91bd --- /dev/null +++ b/pkg/views/src/assets/utils.css @@ -0,0 +1,11 @@ +html, body, #app, .v-application { + overflow: auto !important; +} + +.no-scrollbar { + scrollbar-width: none; +} + +.no-scrollbar::-webkit-scrollbar { + width: 0; +} diff --git a/pkg/views/src/components/posts/PostItem.vue b/pkg/views/src/components/posts/PostItem.vue new file mode 100644 index 0000000..844105f --- /dev/null +++ b/pkg/views/src/components/posts/PostItem.vue @@ -0,0 +1,31 @@ + + + + + \ No newline at end of file diff --git a/pkg/views/src/components/posts/PostList.vue b/pkg/views/src/components/posts/PostList.vue new file mode 100644 index 0000000..4cb9771 --- /dev/null +++ b/pkg/views/src/components/posts/PostList.vue @@ -0,0 +1,21 @@ + + + diff --git a/pkg/views/src/layouts/master.vue b/pkg/views/src/layouts/master.vue index 9db7e29..a161a8d 100644 --- a/pkg/views/src/layouts/master.vue +++ b/pkg/views/src/layouts/master.vue @@ -1,13 +1,24 @@ - diff --git a/pkg/views/src/main.ts b/pkg/views/src/main.ts index aa2849e..b517f0b 100644 --- a/pkg/views/src/main.ts +++ b/pkg/views/src/main.ts @@ -1,41 +1,50 @@ -import "virtual:uno.css" +import "virtual:uno.css"; -import { createApp } from "vue" -import { createPinia } from "pinia" +import "./assets/utils.css"; -import "vuetify/styles" -import { createVuetify } from "vuetify" -import * as components from "vuetify/components" -import * as directives from "vuetify/directives" +import { createApp } from "vue"; +import { createPinia } from "pinia"; -import "@mdi/font/css/materialdesignicons.min.css" +import "vuetify/styles"; +import { createVuetify } from "vuetify"; +import { md3 } from "vuetify/blueprints"; +import * as components from "vuetify/components"; +import * as directives from "vuetify/directives"; -import index from "./index.vue" -import router from "./router" +import "@mdi/font/css/materialdesignicons.min.css"; +import "@fontsource/roboto/latin.css"; +import "@unocss/reset/tailwind.css"; -const app = createApp(index) +import index from "./index.vue"; +import router from "./router"; + +const app = createApp(index); app.use( createVuetify({ components, directives, + blueprint: md3, theme: { + defaultTheme: "original", themes: { - light: { - primary: "#4a5099", - secondary: "#2196f3", - accent: "#009688", - error: "#f44336", - warning: "#ff9800", - info: "#03a9f4", - success: "#4caf50" + original: { + colors: { + primary: "#4a5099", + secondary: "#2196f3", + accent: "#009688", + error: "#f44336", + warning: "#ff9800", + info: "#03a9f4", + success: "#4caf50" + } } } } }) -) +); -app.use(createPinia()) -app.use(router) +app.use(createPinia()); +app.use(router); -app.mount("#app") +app.mount("#app"); diff --git a/pkg/views/src/router/index.ts b/pkg/views/src/router/index.ts index 6963185..4943d0f 100644 --- a/pkg/views/src/router/index.ts +++ b/pkg/views/src/router/index.ts @@ -1,6 +1,5 @@ import { createRouter, createWebHistory } from "vue-router" import MasterLayout from "@/layouts/master.vue" -import LandingPage from "@/views/landing.vue" const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), @@ -11,8 +10,8 @@ const router = createRouter({ children: [ { path: "/", - name: "landing", - component: LandingPage + name: "explore", + component: () => import("@/views/explore.vue") } ] } diff --git a/pkg/views/src/scripts/request.ts b/pkg/views/src/scripts/request.ts new file mode 100644 index 0000000..5540ff2 --- /dev/null +++ b/pkg/views/src/scripts/request.ts @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..2f4f1a8 --- /dev/null +++ b/pkg/views/src/stores/userinfo.ts @@ -0,0 +1,56 @@ +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 new file mode 100644 index 0000000..431cf84 --- /dev/null +++ b/pkg/views/src/stores/wellKnown.ts @@ -0,0 +1,14 @@ +import { request } from "@/scripts/request" +import { defineStore } from "pinia" +import { ref } from "vue" + +export const useWellKnown = defineStore("well-known", () => { + const wellKnown = ref({}) + + async function readWellKnown() { + const res = await request("/.well-known") + wellKnown.value = await res.json() + } + + return { wellKnown, readWellKnown } +}) diff --git a/pkg/views/src/views/explore.vue b/pkg/views/src/views/explore.vue new file mode 100644 index 0000000..eeb2ef9 --- /dev/null +++ b/pkg/views/src/views/explore.vue @@ -0,0 +1,59 @@ + + + \ No newline at end of file diff --git a/pkg/views/src/views/landing.vue b/pkg/views/src/views/landing.vue deleted file mode 100644 index a02994a..0000000 --- a/pkg/views/src/views/landing.vue +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/pkg/views/tsconfig.app.json b/pkg/views/tsconfig.app.json index e14c754..292c91d 100644 --- a/pkg/views/tsconfig.app.json +++ b/pkg/views/tsconfig.app.json @@ -4,6 +4,8 @@ "exclude": ["src/**/__tests__/*"], "compilerOptions": { "composite": true, + "allowJs": true, + "checkJs": true, "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "baseUrl": ".", diff --git a/pkg/views/vite.config.ts b/pkg/views/vite.config.ts index 7dbfdfa..ed08b91 100644 --- a/pkg/views/vite.config.ts +++ b/pkg/views/vite.config.ts @@ -12,5 +12,11 @@ export default defineConfig({ alias: { "@": fileURLToPath(new URL("./src", import.meta.url)) } + }, + server: { + proxy: { + "/.well-known": "http://localhost:8445", + "/api": "http://localhost:8445" + } } })