12 Commits

Author SHA1 Message Date
015040cc1d chore: upgrade version 2023-10-17 23:02:07 +08:00
c8869e67c7 chore: update font family 2023-10-17 22:59:39 +08:00
a9ae7d2e96 chore: update frontend deps 2023-10-17 22:30:19 +08:00
db9034ccf9 chore: update buf deps 2023-10-17 22:01:00 +08:00
4d1705dca5 chore: update bin folder 2023-10-17 21:56:24 +08:00
3225e7c47b chore: update server structure 2023-10-17 21:54:22 +08:00
328397612c chore(deps): bump golang.org/x/net from 0.12.0 to 0.17.0 (#39)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.12.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.12.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-12 11:05:52 -05:00
c846cde5b4 chore: update readme 2023-10-05 08:32:26 +08:00
5c2cb99866 chore: update logo image 2023-10-05 08:31:39 +08:00
742c7da2eb fix: i18n AMO links (#38) 2023-10-01 08:20:34 -05:00
88b247410f chore: update readme about extension 2023-10-01 12:53:56 +08:00
01417943fb chore: update readme about extension 2023-10-01 12:50:34 +08:00
33 changed files with 849 additions and 645 deletions

View File

@ -15,9 +15,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: bufbuild/buf-setup-action@v1
- run: buf generate
working-directory: proto
- uses: pnpm/action-setup@v2.2.4 - uses: pnpm/action-setup@v2.2.4
with: with:
version: 8 version: 8
@ -28,6 +25,8 @@ jobs:
cache-dependency-path: "frontend/extension/pnpm-lock.yaml" cache-dependency-path: "frontend/extension/pnpm-lock.yaml"
- run: pnpm install - run: pnpm install
working-directory: frontend/extension working-directory: frontend/extension
- run: pnpm type-gen
working-directory: frontend/extension
- name: Run eslint check - name: Run eslint check
run: pnpm lint run: pnpm lint
working-directory: frontend/extension working-directory: frontend/extension
@ -36,9 +35,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: bufbuild/buf-setup-action@v1
- run: buf generate
working-directory: proto
- uses: pnpm/action-setup@v2.2.4 - uses: pnpm/action-setup@v2.2.4
with: with:
version: 8 version: 8
@ -49,6 +45,8 @@ jobs:
cache-dependency-path: "frontend/extension/pnpm-lock.yaml" cache-dependency-path: "frontend/extension/pnpm-lock.yaml"
- run: pnpm install - run: pnpm install
working-directory: frontend/extension working-directory: frontend/extension
- run: pnpm type-gen
working-directory: frontend/extension
- name: Run extension build - name: Run extension build
run: pnpm build run: pnpm build
working-directory: frontend/extension working-directory: frontend/extension

View File

@ -15,9 +15,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: bufbuild/buf-setup-action@v1
- run: buf generate
working-directory: proto
- uses: pnpm/action-setup@v2.2.4 - uses: pnpm/action-setup@v2.2.4
with: with:
version: 8 version: 8
@ -28,6 +25,8 @@ jobs:
cache-dependency-path: "frontend/web/pnpm-lock.yaml" cache-dependency-path: "frontend/web/pnpm-lock.yaml"
- run: pnpm install - run: pnpm install
working-directory: frontend/web working-directory: frontend/web
- run: pnpm type-gen
working-directory: frontend/web
- name: Run eslint check - name: Run eslint check
run: pnpm lint run: pnpm lint
working-directory: frontend/web working-directory: frontend/web
@ -36,9 +35,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: bufbuild/buf-setup-action@v1
- run: buf generate
working-directory: proto
- uses: pnpm/action-setup@v2.2.4 - uses: pnpm/action-setup@v2.2.4
with: with:
version: 8 version: 8
@ -49,6 +45,8 @@ jobs:
cache-dependency-path: "frontend/web/pnpm-lock.yaml" cache-dependency-path: "frontend/web/pnpm-lock.yaml"
- run: pnpm install - run: pnpm install
working-directory: frontend/web working-directory: frontend/web
- run: pnpm type-gen
working-directory: frontend/web
- name: Run frontend build - name: Run frontend build
run: pnpm build run: pnpm build
working-directory: frontend/web working-directory: frontend/web

View File

@ -1,26 +1,12 @@
# Build protobuf.
FROM golang:1.21-alpine AS protobuf
WORKDIR /protobuf-generate
COPY . .
RUN GO111MODULE=on GOBIN=/usr/local/bin go install github.com/bufbuild/buf/cmd/buf@v1.26.1
WORKDIR /protobuf-generate/proto
RUN buf generate
# Build frontend dist. # Build frontend dist.
FROM node:18-alpine AS frontend FROM node:18-alpine AS frontend
WORKDIR /frontend-build WORKDIR /frontend-build
COPY ./frontend . COPY . .
COPY --from=protobuf /protobuf-generate/frontend/web/src/types/proto ./web/src/types/proto WORKDIR /frontend-build/frontend/web
WORKDIR /frontend-build/web RUN corepack enable && pnpm i --frozen-lockfile && pnpm type-gen
RUN corepack enable && pnpm i --frozen-lockfile
RUN pnpm build RUN pnpm build
@ -29,9 +15,9 @@ FROM golang:1.21-alpine AS backend
WORKDIR /backend-build WORKDIR /backend-build
COPY . . COPY . .
COPY --from=frontend /frontend-build/web/dist ./server/dist COPY --from=frontend /frontend-build/frontend/web/dist ./server/dist
RUN CGO_ENABLED=0 go build -o slash ./cmd/slash/main.go RUN CGO_ENABLED=0 go build -o slash ./bin/slash/main.go
# Make workspace with above generated files. # Make workspace with above generated files.
FROM alpine:latest AS monolithic FROM alpine:latest AS monolithic

View File

@ -4,6 +4,8 @@
**Slash** is an open source, self-hosted bookmarks and link sharing platform. It allows you to organize your links with tags, and share them using custom shortened URLs. Slash also supports team sharing of link libraries for easy collaboration. **Slash** is an open source, self-hosted bookmarks and link sharing platform. It allows you to organize your links with tags, and share them using custom shortened URLs. Slash also supports team sharing of link libraries for easy collaboration.
🧩 Browser extension(v1.0.0) now available! - [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg), [Firefox Add-on](https://addons.mozilla.org/firefox/addon/your-slash/)
<a href="https://demo.slash.yourselfhosted.com">Live Demo</a><a href="https://discord.gg/QZqUuUAhDV">Discord</a> <a href="https://demo.slash.yourselfhosted.com">Live Demo</a><a href="https://discord.gg/QZqUuUAhDV">Discord</a>
<p> <p>
@ -11,9 +13,6 @@
<a href="https://github.com/boojack/slash/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/boojack/slash?logo=github"/></a> <a href="https://github.com/boojack/slash/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/boojack/slash?logo=github"/></a>
</p> </p>
<p align="center">
<a href="https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg"><b>🧩 Browser extension now available!</b></a></p>
![demo](./resources/demo.png) ![demo](./resources/demo.png)
## Features ## Features
@ -38,8 +37,12 @@ Slash provides a browser extension to help you use your shortcuts in the search
![browser-extension-example](./resources/browser-extension-example.png) ![browser-extension-example](./resources/browser-extension-example.png)
Learn more in [The Browser Extension of Slash](https://github.com/boojack/slash/blob/main/docs/install-browser-extension.md).
### Chromium based browsers ### Chromium based browsers
For Chromium based browsers(Chrome, Edge, Arc, ...), you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg). For Chromium based browsers(Chrome, Edge, Arc, ...), you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg).
Learn more in [The Browser Extension of Slash](https://github.com/boojack/slash/blob/main/docs/install-browser-extension.md). ### Firefox
For Firefox, you can install the extension from the [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/your-slash/).

View File

@ -10,6 +10,7 @@ import (
"github.com/mssola/useragent" "github.com/mssola/useragent"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"github.com/boojack/slash/server/metric"
"github.com/boojack/slash/store" "github.com/boojack/slash/store"
) )
@ -78,6 +79,7 @@ func (s *APIV1Service) registerAnalyticsRoutes(g *echo.Group) {
browserMap[browserName]++ browserMap[browserName]++
} }
metric.Enqueue("shortcut analytics")
return c.JSON(http.StatusOK, &AnalysisData{ return c.JSON(http.StatusOK, &AnalysisData{
ReferenceData: mapToReferenceInfoSlice(referenceMap), ReferenceData: mapToReferenceInfoSlice(referenceMap),
DeviceData: mapToDeviceInfoSlice(deviceMap), DeviceData: mapToDeviceInfoSlice(deviceMap),

View File

@ -13,6 +13,7 @@ import (
"github.com/boojack/slash/api/auth" "github.com/boojack/slash/api/auth"
storepb "github.com/boojack/slash/proto/gen/store" storepb "github.com/boojack/slash/proto/gen/store"
"github.com/boojack/slash/server/metric"
"github.com/boojack/slash/server/service/license" "github.com/boojack/slash/server/service/license"
"github.com/boojack/slash/store" "github.com/boojack/slash/store"
) )
@ -63,6 +64,7 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) {
cookieExp := time.Now().Add(auth.CookieExpDuration) cookieExp := time.Now().Add(auth.CookieExpDuration)
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp) setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
metric.Enqueue("user sign in")
return c.JSON(http.StatusOK, convertUserFromStore(user)) return c.JSON(http.StatusOK, convertUserFromStore(user))
}) })
@ -129,6 +131,7 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) {
cookieExp := time.Now().Add(auth.CookieExpDuration) cookieExp := time.Now().Add(auth.CookieExpDuration)
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp) setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
metric.Enqueue("user sign up")
return c.JSON(http.StatusOK, convertUserFromStore(user)) return c.JSON(http.StatusOK, convertUserFromStore(user))
}) })

View File

@ -12,6 +12,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
storepb "github.com/boojack/slash/proto/gen/store" storepb "github.com/boojack/slash/proto/gen/store"
"github.com/boojack/slash/server/metric"
"github.com/boojack/slash/store" "github.com/boojack/slash/store"
) )
@ -46,6 +47,7 @@ func (s *APIV1Service) registerRedirectorRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to create activity, err: %s", err)).SetInternal(err) return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to create activity, err: %s", err)).SetInternal(err)
} }
metric.Enqueue("shortcut redirect")
return redirectToShortcut(c, shortcut) return redirectToShortcut(c, shortcut)
}) })
} }

View File

@ -12,6 +12,7 @@ import (
"github.com/boojack/slash/internal/util" "github.com/boojack/slash/internal/util"
storepb "github.com/boojack/slash/proto/gen/store" storepb "github.com/boojack/slash/proto/gen/store"
"github.com/boojack/slash/server/metric"
"github.com/boojack/slash/store" "github.com/boojack/slash/store"
) )
@ -121,6 +122,7 @@ func (s *APIV1Service) registerShortcutRoutes(g *echo.Group) {
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to compose shortcut, err: %s", err)).SetInternal(err) return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to compose shortcut, err: %s", err)).SetInternal(err)
} }
metric.Enqueue("shortcut create")
return c.JSON(http.StatusOK, shortcutMessage) return c.JSON(http.StatusOK, shortcutMessage)
}) })

View File

@ -11,6 +11,7 @@ import (
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"github.com/boojack/slash/internal/util" "github.com/boojack/slash/internal/util"
"github.com/boojack/slash/server/metric"
"github.com/boojack/slash/server/service/license" "github.com/boojack/slash/server/service/license"
"github.com/boojack/slash/store" "github.com/boojack/slash/store"
) )
@ -137,6 +138,7 @@ func (s *APIV1Service) registerUserRoutes(g *echo.Group) {
} }
userMessage := convertUserFromStore(user) userMessage := convertUserFromStore(user)
metric.Enqueue("user create")
return c.JSON(http.StatusOK, userMessage) return c.JSON(http.StatusOK, userMessage)
}) })

View File

@ -121,10 +121,6 @@ func (s *WorkspaceService) UpdateWorkspaceSetting(ctx context.Context, request *
return nil, status.Errorf(codes.Internal, "failed to update workspace setting: %v", err) return nil, status.Errorf(codes.Internal, "failed to update workspace setting: %v", err)
} }
} else if path == "custom_style" { } else if path == "custom_style" {
if !s.LicenseService.IsFeatureEnabled(license.FeatureTypeCustomeStyle) {
return nil, status.Errorf(codes.PermissionDenied, "feature custom style is not available")
}
if _, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{ if _, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE, Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE,
Value: &storepb.WorkspaceSetting_CustomStyle{ Value: &storepb.WorkspaceSetting_CustomStyle{

View File

@ -15,6 +15,7 @@ import (
"github.com/boojack/slash/internal/log" "github.com/boojack/slash/internal/log"
"github.com/boojack/slash/server" "github.com/boojack/slash/server"
"github.com/boojack/slash/server/metric"
"github.com/boojack/slash/server/profile" "github.com/boojack/slash/server/profile"
"github.com/boojack/slash/store" "github.com/boojack/slash/store"
"github.com/boojack/slash/store/db" "github.com/boojack/slash/store/db"
@ -50,6 +51,9 @@ var (
return return
} }
// nolint
metric.NewMetricClient(s.Secret, *serverProfile)
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
// Trigger graceful shutdown on SIGINT or SIGTERM. // Trigger graceful shutdown on SIGINT or SIGTERM.
// The default signal sent by the `kill` command is SIGTERM, // The default signal sent by the `kill` command is SIGTERM,

View File

@ -8,7 +8,7 @@ Slash provides a browser extension to help you use your shortcuts in the search
For Chromuim based browsers, you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg). For Chromuim based browsers, you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg).
For Firefox, we don't support the Firefox Add-ons platform yet. And we are working on it. For Firefox, you can install the extension from the [Firefox Add-ons](https://addons.mozilla.org/en-US/firefox/addon/your-slash/).
### Generate an access token ### Generate an access token

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 257 KiB

View File

@ -8,13 +8,14 @@
"build": "plasmo build", "build": "plasmo build",
"package": "plasmo package", "package": "plasmo package",
"lint": "eslint --ext .js,.ts,.tsx, src", "lint": "eslint --ext .js,.ts,.tsx, src",
"lint-fix": "eslint --ext .js,.ts,.tsx, src --fix" "lint-fix": "eslint --ext .js,.ts,.tsx, src --fix",
"type-gen": "cd ../../proto && buf generate"
}, },
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.1", "@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0", "@emotion/styled": "^11.11.0",
"@mui/joy": "5.0.0-beta.0", "@mui/joy": "5.0.0-beta.0",
"@plasmohq/storage": "^1.8.0", "@plasmohq/storage": "^1.8.1",
"axios": "^1.5.1", "axios": "^1.5.1",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
@ -23,19 +24,20 @@
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hot-toast": "^2.4.1", "react-hot-toast": "^2.4.1",
"zustand": "^4.4.1" "zustand": "^4.4.3"
}, },
"devDependencies": { "devDependencies": {
"@bufbuild/buf": "^1.27.0",
"@trivago/prettier-plugin-sort-imports": "4.1.0", "@trivago/prettier-plugin-sort-imports": "4.1.0",
"@types/chrome": "0.0.241", "@types/chrome": "0.0.241",
"@types/lodash-es": "^4.17.9", "@types/lodash-es": "^4.17.9",
"@types/node": "20.4.2", "@types/node": "20.4.2",
"@types/react": "18.2.15", "@types/react": "18.2.15",
"@types/react-dom": "18.2.7", "@types/react-dom": "18.2.7",
"@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/eslint-plugin": "^6.8.0",
"@typescript-eslint/parser": "^6.7.3", "@typescript-eslint/parser": "^6.8.0",
"autoprefixer": "^10.4.16", "autoprefixer": "^10.4.16",
"eslint": "^8.50.0", "eslint": "^8.51.0",
"eslint-config-prettier": "^8.10.0", "eslint-config-prettier": "^8.10.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.33.2", "eslint-plugin-react": "^7.33.2",

File diff suppressed because it is too large Load Diff

View File

@ -5,13 +5,14 @@
"build": "tsc && vite build", "build": "tsc && vite build",
"serve": "vite preview", "serve": "vite preview",
"lint": "eslint --ext .js,.ts,.tsx, src", "lint": "eslint --ext .js,.ts,.tsx, src",
"lint-fix": "eslint --ext .js,.ts,.tsx, src --fix" "lint-fix": "eslint --ext .js,.ts,.tsx, src --fix",
"type-gen": "cd ../../proto && buf generate"
}, },
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.1", "@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0", "@emotion/styled": "^11.11.0",
"@mui/joy": "5.0.0-beta.7", "@mui/joy": "5.0.0-beta.7",
"@reduxjs/toolkit": "^1.9.6", "@reduxjs/toolkit": "^1.9.7",
"axios": "^0.27.2", "axios": "^0.27.2",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"copy-to-clipboard": "^3.3.3", "copy-to-clipboard": "^3.3.3",
@ -24,23 +25,24 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1", "react-hot-toast": "^2.4.1",
"react-i18next": "^13.2.2", "react-i18next": "^13.3.0",
"react-redux": "^8.1.2", "react-redux": "^8.1.3",
"react-router-dom": "^6.16.0", "react-router-dom": "^6.17.0",
"react-use": "^17.4.0", "react-use": "^17.4.0",
"tailwindcss": "^3.3.3", "tailwindcss": "^3.3.3",
"zustand": "^4.4.1" "zustand": "^4.4.3"
}, },
"devDependencies": { "devDependencies": {
"@bufbuild/buf": "^1.27.0",
"@trivago/prettier-plugin-sort-imports": "^4.2.0", "@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@types/lodash-es": "^4.17.9", "@types/lodash-es": "^4.17.9",
"@types/react": "^18.2.23", "@types/react": "^18.2.28",
"@types/react-dom": "^18.2.8", "@types/react-dom": "^18.2.13",
"@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/eslint-plugin": "^6.8.0",
"@typescript-eslint/parser": "^6.7.3", "@typescript-eslint/parser": "^6.8.0",
"@vitejs/plugin-react-swc": "^3.4.0", "@vitejs/plugin-react-swc": "^3.4.0",
"autoprefixer": "^10.4.16", "autoprefixer": "^10.4.16",
"eslint": "^8.50.0", "eslint": "^8.51.0",
"eslint-config-prettier": "^8.10.0", "eslint-config-prettier": "^8.10.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.33.2", "eslint-plugin-react": "^7.33.2",
@ -49,6 +51,6 @@
"prettier": "2.6.2", "prettier": "2.6.2",
"protobufjs": "^7.2.5", "protobufjs": "^7.2.5",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"vite": "^4.4.9" "vite": "^4.4.11"
} }
} }

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 257 KiB

View File

@ -29,7 +29,7 @@ const Header: React.FC = () => {
<div className="w-full max-w-6xl mx-auto px-3 md:px-12 py-5 flex flex-row justify-between items-center"> <div className="w-full max-w-6xl mx-auto px-3 md:px-12 py-5 flex flex-row justify-between items-center">
<div className="flex flex-row justify-start items-center shrink mr-2"> <div className="flex flex-row justify-start items-center shrink mr-2">
<Link to="/" className="text-lg cursor-pointer flex flex-row justify-start items-center dark:text-gray-400"> <Link to="/" className="text-lg cursor-pointer flex flex-row justify-start items-center dark:text-gray-400">
<img id="logo-img" src="/logo.png" className="w-8 h-auto mr-2 -mt-0.5 dark:opacity-80" alt="" /> <img id="logo-img" src="/logo.png" className="w-8 h-auto mr-2 -mt-0.5 dark:opacity-80 rounded-full shadow" alt="" />
Slash Slash
</Link> </Link>
{profile.plan === PlanType.PRO && ( {profile.plan === PlanType.PRO && (

View File

@ -93,14 +93,14 @@ const ShortcutView = (props: Props) => {
return ( return (
<span <span
key={tag} key={tag}
className="max-w-[8rem] truncate text-gray-400 dark:text-gray-500 text-sm font-mono leading-4 cursor-pointer hover:opacity-80" className="max-w-[8rem] truncate text-gray-400 dark:text-gray-500 text-sm leading-4 cursor-pointer hover:opacity-80"
onClick={() => viewStore.setFilter({ tag: tag })} onClick={() => viewStore.setFilter({ tag: tag })}
> >
#{tag} #{tag}
</span> </span>
); );
})} })}
{shortcut.tags.length === 0 && <span className="text-gray-400 text-sm font-mono leading-4 italic">No tags</span>} {shortcut.tags.length === 0 && <span className="text-gray-400 text-sm leading-4 italic">No tags</span>}
</div> </div>
<div className="w-full flex mt-2 gap-2 overflow-x-auto"> <div className="w-full flex mt-2 gap-2 overflow-x-auto">
<Tooltip title="Creator" variant="solid" placement="top" arrow> <Tooltip title="Creator" variant="solid" placement="top" arrow>

View File

@ -63,6 +63,7 @@ const WorkspaceSection: React.FC = () => {
<p className="mt-2 dark:text-gray-400">{t("settings.workspace.custom-style")}</p> <p className="mt-2 dark:text-gray-400">{t("settings.workspace.custom-style")}</p>
<Textarea <Textarea
className="w-full mt-2" className="w-full mt-2"
placeholder="* {font-family: ui-monospace Monaco Consolas;}"
minRows={2} minRows={2}
maxRows={5} maxRows={5}
value={workspaceSetting.customStyle} value={workspaceSetting.customStyle}

View File

@ -137,14 +137,12 @@ const ShortcutDetail = () => {
<div className="mt-4 ml-1 flex flex-row justify-start items-start flex-wrap gap-2"> <div className="mt-4 ml-1 flex flex-row justify-start items-start flex-wrap gap-2">
{shortcut.tags.map((tag) => { {shortcut.tags.map((tag) => {
return ( return (
<span key={tag} className="max-w-[8rem] truncate text-gray-400 text font-mono leading-4 dark:text-gray-500"> <span key={tag} className="max-w-[8rem] truncate text-gray-400 text leading-4 dark:text-gray-500">
#{tag} #{tag}
</span> </span>
); );
})} })}
{shortcut.tags.length === 0 && ( {shortcut.tags.length === 0 && <span className="text-gray-400 text-sm leading-4 italic dark:text-gray-500">No tags</span>}
<span className="text-gray-400 text-sm font-mono leading-4 italic dark:text-gray-500">No tags</span>
)}
</div> </div>
<div className="w-full flex mt-4 gap-2"> <div className="w-full flex mt-4 gap-2">
<Tooltip title="Creator" variant="solid" placement="top" arrow> <Tooltip title="Creator" variant="solid" placement="top" arrow>

View File

@ -71,7 +71,7 @@ const SignIn: React.FC = () => {
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center"> <div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
<div className="w-full py-4 grow flex flex-col justify-center items-center"> <div className="w-full py-4 grow flex flex-col justify-center items-center">
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4"> <div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
<img id="logo-img" src="/logo.png" className="w-12 h-auto mr-2 -mt-1" alt="logo" /> <img id="logo-img" src="/logo.png" className="w-12 h-auto mr-2 -mt-1 rounded-full shadow" alt="logo" />
<span className="text-3xl opacity-80 dark:text-gray-500">Slash</span> <span className="text-3xl opacity-80 dark:text-gray-500">Slash</span>
</div> </div>
<form className="w-full mt-6" onSubmit={handleSigninBtnClick}> <form className="w-full mt-6" onSubmit={handleSigninBtnClick}>

View File

@ -78,7 +78,7 @@ const SignUp: React.FC = () => {
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center"> <div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
<div className="w-full py-4 grow flex flex-col justify-center items-center"> <div className="w-full py-4 grow flex flex-col justify-center items-center">
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4"> <div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
<img id="logo-img" src="/logo.png" className="w-12 h-auto mr-2 -mt-1" alt="logo" /> <img id="logo-img" src="/logo.png" className="w-12 h-auto mr-2 -mt-1 rounded-full shadow" alt="logo" />
<span className="text-3xl opacity-80 dark:text-gray-500">Slash</span> <span className="text-3xl opacity-80 dark:text-gray-500">Slash</span>
</div> </div>
<p className="w-full text-2xl mt-6 dark:text-gray-500">{t("auth.create-your-account")}</p> <p className="w-full text-2xl mt-6 dark:text-gray-500">{t("auth.create-your-account")}</p>

9
go.mod
View File

@ -10,10 +10,10 @@ require (
github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-isatty v0.0.19 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/crypto v0.11.0 golang.org/x/crypto v0.14.0
golang.org/x/net v0.12.0 // indirect golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.10.0 // indirect golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.11.0 // indirect golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect
) )
@ -78,6 +78,7 @@ require (
github.com/mssola/useragent v1.0.0 github.com/mssola/useragent v1.0.0
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/posthog/posthog-go v0.0.0-20230801140217-d607812dee69
go.uber.org/zap v1.21.0 go.uber.org/zap v1.21.0
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
golang.org/x/mod v0.11.0 golang.org/x/mod v0.11.0

19
go.sum
View File

@ -390,6 +390,8 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posthog/posthog-go v0.0.0-20230801140217-d607812dee69 h1:01dHVodha5BzrMtVmcpPeA4VYbZEsTXQ6m4123zQXJk=
github.com/posthog/posthog-go v0.0.0-20230801140217-d607812dee69/go.mod h1:migYMxlAqcnQy+3eN8mcL0b2tpKy6R+8Zc0lxwk4dKM=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
@ -476,6 +478,7 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
@ -525,8 +528,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -608,8 +611,8 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -692,8 +695,8 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -702,8 +705,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -3,7 +3,7 @@ tmp_dir = ".air"
[build] [build]
bin = "./.air/slash --mode dev" bin = "./.air/slash --mode dev"
cmd = "go build -o ./.air/slash ./cmd/slash/main.go" cmd = "go build -o ./.air/slash ./bin/slash/main.go"
delay = 1000 delay = 1000
exclude_dir = [".air", "frontend", "build"] exclude_dir = [".air", "frontend", "build"]
exclude_file = [] exclude_file = []

51
server/metric/metric.go Normal file
View File

@ -0,0 +1,51 @@
package metric
import (
"github.com/posthog/posthog-go"
"github.com/boojack/slash/server/profile"
)
const (
PostHogAPIKey = "phc_YFEi1aqUBW9sX2KDzdvMtK43DNu0mkeoKMKc0EQum2t"
)
var (
client *MetricClient
)
type MetricClient struct {
workspaceID string
profile *profile.Profile
phClient *posthog.Client
}
func NewMetricClient(workspaceID string, profile profile.Profile) (*MetricClient, error) {
phClient, err := posthog.NewWithConfig(PostHogAPIKey, posthog.Config{
Endpoint: "https://app.posthog.com",
})
if err != nil {
return nil, err
}
client = &MetricClient{
workspaceID: workspaceID,
profile: &profile,
phClient: &phClient,
}
return client, nil
}
func Enqueue(event string) {
if client == nil {
return
}
if client.profile.Mode != "prod" {
return
}
// nolint
(*client.phClient).Enqueue(posthog.Capture{
DistinctId: `slash-` + client.workspaceID,
Event: event,
})
}

View File

@ -18,6 +18,7 @@ import (
apiv2 "github.com/boojack/slash/api/v2" apiv2 "github.com/boojack/slash/api/v2"
"github.com/boojack/slash/internal/log" "github.com/boojack/slash/internal/log"
storepb "github.com/boojack/slash/proto/gen/store" storepb "github.com/boojack/slash/proto/gen/store"
"github.com/boojack/slash/server/metric"
"github.com/boojack/slash/server/profile" "github.com/boojack/slash/server/profile"
"github.com/boojack/slash/server/service/license" "github.com/boojack/slash/server/service/license"
"github.com/boojack/slash/server/service/resource" "github.com/boojack/slash/server/service/resource"
@ -29,6 +30,7 @@ type Server struct {
Profile *profile.Profile Profile *profile.Profile
Store *store.Store Store *store.Store
Secret string
licenseService *license.LicenseService licenseService *license.LicenseService
@ -93,11 +95,12 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
secret := "slash" secret := "slash"
if profile.Mode == "prod" { if profile.Mode == "prod" {
var err error var err error
secret, err = s.getSystemSecretSessionName(ctx) secret, err = s.getSecretSessionName(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
s.Secret = secret
rootGroup := e.Group("") rootGroup := e.Group("")
// Register API v1 routes. // Register API v1 routes.
@ -133,6 +136,7 @@ func (s *Server) Start(ctx context.Context) error {
} }
}() }()
metric.Enqueue("server start")
return s.e.Start(fmt.Sprintf(":%d", s.Profile.Port)) return s.e.Start(fmt.Sprintf(":%d", s.Profile.Port))
} }
@ -161,7 +165,7 @@ func grpcRequestSkipper(c echo.Context) bool {
return strings.HasPrefix(c.Request().URL.Path, "/slash.api.v2.") return strings.HasPrefix(c.Request().URL.Path, "/slash.api.v2.")
} }
func (s *Server) getSystemSecretSessionName(ctx context.Context) (string, error) { func (s *Server) getSecretSessionName(ctx context.Context) (string, error) {
secretSessionSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ secretSessionSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION, Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION,
}) })

View File

@ -9,10 +9,10 @@ import (
// Version is the service current released version. // Version is the service current released version.
// Semantic versioning: https://semver.org/ // Semantic versioning: https://semver.org/
var Version = "0.4.5" var Version = "0.4.6"
// DevVersion is the service current development version. // DevVersion is the service current development version.
var DevVersion = "0.4.5" var DevVersion = "0.4.6"
func GetCurrentVersion(mode string) string { func GetCurrentVersion(mode string) string {
if mode == "dev" || mode == "demo" { if mode == "dev" || mode == "demo" {