mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-20 22:07:15 +00:00
chore: rename to slash
This commit is contained in:
parent
fcd72e1f98
commit
b36572c5be
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -5,7 +5,7 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Thanks for taking the time to suggest an idea for Shortify!
|
Thanks for taking the time to suggest an idea for Slash!
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Is your feature request related to a problem?
|
label: Is your feature request related to a problem?
|
||||||
|
@ -41,4 +41,4 @@ jobs:
|
|||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: stevenlgtm/shortify:latest, stevenlgtm/shortify:${{ env.VERSION }}
|
tags: stevenlgtm/slash:latest, stevenlgtm/slash:${{ env.VERSION }}
|
||||||
|
@ -34,4 +34,4 @@ jobs:
|
|||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
push: true
|
push: true
|
||||||
tags: stevenlgtm/shortify:test
|
tags: stevenlgtm/slash:test
|
||||||
|
10
Dockerfile
10
Dockerfile
@ -17,18 +17,18 @@ WORKDIR /backend-build
|
|||||||
COPY . .
|
COPY . .
|
||||||
COPY --from=frontend /frontend-build/dist ./server/dist
|
COPY --from=frontend /frontend-build/dist ./server/dist
|
||||||
|
|
||||||
RUN go build -o shortify ./cmd/shortify/main.go
|
RUN go build -o slash ./cmd/slash/main.go
|
||||||
|
|
||||||
# Make workspace with above generated files.
|
# Make workspace with above generated files.
|
||||||
FROM alpine:3.16 AS monolithic
|
FROM alpine:3.16 AS monolithic
|
||||||
WORKDIR /usr/local/shortify
|
WORKDIR /usr/local/slash
|
||||||
|
|
||||||
RUN apk add --no-cache tzdata
|
RUN apk add --no-cache tzdata
|
||||||
ENV TZ="UTC"
|
ENV TZ="UTC"
|
||||||
|
|
||||||
COPY --from=backend /backend-build/shortify /usr/local/shortify/
|
COPY --from=backend /backend-build/slash /usr/local/slash/
|
||||||
|
|
||||||
# Directory to store the data, which can be referenced as the mounting point.
|
# Directory to store the data, which can be referenced as the mounting point.
|
||||||
RUN mkdir -p /var/opt/shortify
|
RUN mkdir -p /var/opt/slash
|
||||||
|
|
||||||
ENTRYPOINT ["./shortify", "--mode", "prod", "--port", "5231"]
|
ENTRYPOINT ["./slash", "--mode", "prod", "--port", "5231"]
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
# Shortify
|
# Slash
|
||||||
|
|
||||||
<img align="right" src="./resources/logo.png" height="64px" alt="logo">
|
<img align="right" src="./resources/logo.png" height="64px" alt="logo">
|
||||||
|
|
||||||
**Shortify** is a bookmarking and short link service that allows you to save and share links easily. It lets you store and categorize links, generate short URLs for easy sharing, search and filter your saved links, and access them from any device. It simplifies link organization, management, and collaboration, making it effortless to navigate and share web resources.
|
**Slash** is a bookmarking and short link service that allows you to save and share links easily. It lets you store and categorize links, generate short URLs for easy sharing, search and filter your saved links, and access them from any device. It simplifies link organization, management, and collaboration, making it effortless to navigate and share web resources.
|
||||||
|
|
||||||
Let's Simplify, Share, and Save your links with **Shortify**.
|
Let's Simplify, Share, and Save your links with **Slash**.
|
||||||
|
|
||||||
## Deploy with Docker in seconds
|
## Deploy with Docker in seconds
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --name shortify -p 5231:5231 -v ~/.shortify/:/var/opt/shortify stevenlgtm/shortify:latest
|
docker run -d --name slash -p 5231:5231 -v ~/.slash/:/var/opt/slash stevenlgtm/slash:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/mssola/useragent"
|
"github.com/mssola/useragent"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/boojack/shortify/api/v1/auth"
|
"github.com/boojack/slash/api/v1/auth"
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
@ -5,14 +5,14 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
issuer = "shortify"
|
issuer = "slash"
|
||||||
// Signing key section. For now, this is only used for signing, not for verifying since we only
|
// Signing key section. For now, this is only used for signing, not for verifying since we only
|
||||||
// have 1 version. But it will be used to maintain backward compatibility if we change the signing mechanism.
|
// have 1 version. But it will be used to maintain backward compatibility if we change the signing mechanism.
|
||||||
keyID = "v1"
|
keyID = "v1"
|
||||||
@ -33,9 +33,9 @@ const (
|
|||||||
// 2. The access token has already expired, we refresh the token so that the ongoing request can pass through.
|
// 2. The access token has already expired, we refresh the token so that the ongoing request can pass through.
|
||||||
CookieExpDuration = refreshTokenDuration - 1*time.Minute
|
CookieExpDuration = refreshTokenDuration - 1*time.Minute
|
||||||
// AccessTokenCookieName is the cookie name of access token.
|
// AccessTokenCookieName is the cookie name of access token.
|
||||||
AccessTokenCookieName = "shortify.access-token"
|
AccessTokenCookieName = "slash.access-token"
|
||||||
// RefreshTokenCookieName is the cookie name of refresh token.
|
// RefreshTokenCookieName is the cookie name of refresh token.
|
||||||
RefreshTokenCookieName = "shortify.refresh-token"
|
RefreshTokenCookieName = "slash.refresh-token"
|
||||||
)
|
)
|
||||||
|
|
||||||
type claimsMessage struct {
|
type claimsMessage struct {
|
||||||
|
@ -7,9 +7,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/boojack/shortify/api/v1/auth"
|
"github.com/boojack/slash/api/v1/auth"
|
||||||
"github.com/boojack/shortify/internal/util"
|
"github.com/boojack/slash/internal/util"
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"net/mail"
|
"net/mail"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/boojack/shortify/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/boojack/shortify/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,10 +12,10 @@ import (
|
|||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
|
|
||||||
"github.com/boojack/shortify/server"
|
"github.com/boojack/slash/server"
|
||||||
_profile "github.com/boojack/shortify/server/profile"
|
_profile "github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/boojack/shortify/store/db"
|
"github.com/boojack/slash/store/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -36,7 +36,7 @@ var (
|
|||||||
data string
|
data string
|
||||||
|
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "shortify",
|
Use: "slash",
|
||||||
Short: "",
|
Short: "",
|
||||||
Run: func(_cmd *cobra.Command, _args []string) {
|
Run: func(_cmd *cobra.Command, _args []string) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
@ -108,7 +108,7 @@ func init() {
|
|||||||
|
|
||||||
viper.SetDefault("mode", "dev")
|
viper.SetDefault("mode", "dev")
|
||||||
viper.SetDefault("port", 8082)
|
viper.SetDefault("port", 8082)
|
||||||
viper.SetEnvPrefix("shortify")
|
viper.SetEnvPrefix("slash")
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() {
|
func initConfig() {
|
@ -1,4 +1,4 @@
|
|||||||
import { getShortifyData } from "./common.js";
|
import { getSlashData } from "./common.js";
|
||||||
|
|
||||||
const urlRegex = /https?:\/\/s\/(.+)/;
|
const urlRegex = /https?:\/\/s\/(.+)/;
|
||||||
|
|
||||||
@ -6,16 +6,16 @@ chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
|
|||||||
if (typeof tab.url === "string") {
|
if (typeof tab.url === "string") {
|
||||||
const matchResult = urlRegex.exec(tab.url);
|
const matchResult = urlRegex.exec(tab.url);
|
||||||
if (matchResult) {
|
if (matchResult) {
|
||||||
const shortifyData = await getShortifyData();
|
const slashData = await getSlashData();
|
||||||
const name = matchResult[1];
|
const name = matchResult[1];
|
||||||
const url = `${shortifyData.domain}/s/${name}`;
|
const url = `${slashData.domain}/s/${name}`;
|
||||||
return chrome.tabs.update({ url });
|
return chrome.tabs.update(tab.id, { url });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
chrome.omnibox.onInputEntered.addListener(async (text) => {
|
chrome.omnibox.onInputEntered.addListener(async (text) => {
|
||||||
const shortifyData = await getShortifyData();
|
const slashData = await getSlashData();
|
||||||
const url = `${shortifyData.domain}/s/${text}`;
|
const url = `${slashData.domain}/s/${text}`;
|
||||||
return chrome.tabs.update({ url });
|
return chrome.tabs.update({ url });
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
export const getShortifyData = () => {
|
export const getSlashData = () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
chrome.storage.local.get(["shortify"], (data) => {
|
chrome.storage.local.get(["slash"], (data) => {
|
||||||
if (data?.shortify) {
|
if (data?.slash) {
|
||||||
resolve(data.shortify);
|
resolve(data.slash);
|
||||||
} else {
|
} else {
|
||||||
reject("shortify data not found");
|
reject("slash data not found");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "Shortify",
|
"name": "Slash",
|
||||||
"description": "",
|
"description": "",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<h2>Shortify extension</h2>
|
<h2>Slash extension</h2>
|
||||||
<div>
|
<div>
|
||||||
<span>Domain</span>
|
<span>Domain</span>
|
||||||
<input id="domain-input" type="text" />
|
<input id="domain-input" type="text" />
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { getShortifyData } from "./common.js";
|
import { getSlashData } from "./common.js";
|
||||||
|
|
||||||
const saveButton = document.body.querySelector("#save-button");
|
const saveButton = document.body.querySelector("#save-button");
|
||||||
const domainInput = document.body.querySelector("#domain-input");
|
const domainInput = document.body.querySelector("#domain-input");
|
||||||
|
|
||||||
saveButton.addEventListener("click", () => {
|
saveButton.addEventListener("click", () => {
|
||||||
chrome.storage.local.set({
|
chrome.storage.local.set({
|
||||||
shortify: {
|
slash: {
|
||||||
domain: domainInput.value,
|
domain: domainInput.value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -13,9 +13,9 @@ saveButton.addEventListener("click", () => {
|
|||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const shortifyData = await getShortifyData();
|
const slashData = await getSlashData();
|
||||||
if (shortifyData) {
|
if (slashData) {
|
||||||
domainInput.value = shortifyData.domain;
|
domainInput.value = slashData.domain;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// do nothing.
|
// do nothing.
|
||||||
|
2
go.mod
2
go.mod
@ -1,4 +1,4 @@
|
|||||||
module github.com/boojack/shortify
|
module github.com/boojack/slash
|
||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ root = "."
|
|||||||
tmp_dir = ".air"
|
tmp_dir = ".air"
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
bin = "./.air/shortify"
|
bin = "./.air/slash"
|
||||||
cmd = "go build -o ./.air/shortify ./cmd/shortify/main.go"
|
cmd = "go build -o ./.air/slash ./cmd/slash/main.go"
|
||||||
delay = 1000
|
delay = 1000
|
||||||
exclude_dir = [".air", "web", "build"]
|
exclude_dir = [".air", "web", "build"]
|
||||||
exclude_file = []
|
exclude_file = []
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/boojack/shortify/internal/util"
|
"github.com/boojack/slash/internal/util"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
)
|
)
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/boojack/shortify/server/version"
|
"github.com/boojack/slash/server/version"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ import (
|
|||||||
type Profile struct {
|
type Profile struct {
|
||||||
// Data is the data directory
|
// Data is the data directory
|
||||||
Data string `json:"-"`
|
Data string `json:"-"`
|
||||||
// DSN points to where Shortify stores its own data
|
// DSN points to store data
|
||||||
DSN string `json:"-"`
|
DSN string `json:"-"`
|
||||||
// Mode can be "prod" or "dev"
|
// Mode can be "prod" or "dev"
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
@ -57,7 +57,7 @@ func GetProfile() (*Profile, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if profile.Mode == "prod" && profile.Data == "" {
|
if profile.Mode == "prod" && profile.Data == "" {
|
||||||
profile.Data = "/var/opt/shortify"
|
profile.Data = "/var/opt/slash"
|
||||||
}
|
}
|
||||||
|
|
||||||
dataDir, err := checkDSN(profile.Data)
|
dataDir, err := checkDSN(profile.Data)
|
||||||
@ -67,7 +67,7 @@ func GetProfile() (*Profile, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
profile.Data = dataDir
|
profile.Data = dataDir
|
||||||
profile.DSN = fmt.Sprintf("%s/shortify_%s.db", dataDir, profile.Mode)
|
profile.DSN = fmt.Sprintf("%s/slash_%s.db", dataDir, profile.Mode)
|
||||||
profile.Version = version.GetCurrentVersion(profile.Mode)
|
profile.Version = version.GetCurrentVersion(profile.Mode)
|
||||||
return &profile, nil
|
return &profile, nil
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
apiv1 "github.com/boojack/shortify/api/v1"
|
apiv1 "github.com/boojack/slash/api/v1"
|
||||||
"github.com/boojack/shortify/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@ -52,7 +52,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
embedFrontend(e)
|
embedFrontend(e)
|
||||||
|
|
||||||
// In dev mode, we'd like to set the const secret key to make signin session persistence.
|
// In dev mode, we'd like to set the const secret key to make signin session persistence.
|
||||||
secret := "shortify"
|
secret := "slash"
|
||||||
if profile.Mode == "prod" {
|
if profile.Mode == "prod" {
|
||||||
var err error
|
var err error
|
||||||
secret, err = s.getSystemSecretSessionName(ctx)
|
secret, err = s.getSystemSecretSessionName(ctx)
|
||||||
|
@ -12,8 +12,8 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/boojack/shortify/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/shortify/server/version"
|
"github.com/boojack/slash/server/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed migration
|
//go:embed migration
|
||||||
@ -89,7 +89,7 @@ func (db *DB) Open(ctx context.Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read raw database file, err: %w", err)
|
return fmt.Errorf("failed to read raw database file, err: %w", err)
|
||||||
}
|
}
|
||||||
backupDBFilePath := fmt.Sprintf("%s/shortify_%s_%d_backup.db", db.profile.Data, db.profile.Version, time.Now().Unix())
|
backupDBFilePath := fmt.Sprintf("%s/slash_%s_%d_backup.db", db.profile.Data, db.profile.Version, time.Now().Unix())
|
||||||
if err := os.WriteFile(backupDBFilePath, rawBytes, 0644); err != nil {
|
if err := os.WriteFile(backupDBFilePath, rawBytes, 0644); err != nil {
|
||||||
return fmt.Errorf("failed to write raw database file, err: %w", err)
|
return fmt.Errorf("failed to write raw database file, err: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/boojack/shortify/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Store provides database access to all raw objects.
|
// Store provides database access to all raw objects.
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/boojack/shortify/store/db"
|
"github.com/boojack/slash/store/db"
|
||||||
test "github.com/boojack/shortify/test"
|
test "github.com/boojack/slash/test"
|
||||||
|
|
||||||
// sqlite driver.
|
// sqlite driver.
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/boojack/shortify/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/boojack/shortify/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/shortify/server/version"
|
"github.com/boojack/slash/server/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getUnusedPort() int {
|
func getUnusedPort() int {
|
||||||
@ -31,7 +31,7 @@ func GetTestingProfile(t *testing.T) *profile.Profile {
|
|||||||
Mode: mode,
|
Mode: mode,
|
||||||
Port: port,
|
Port: port,
|
||||||
Data: dir,
|
Data: dir,
|
||||||
DSN: fmt.Sprintf("%s/shortify_%s.db", dir, mode),
|
DSN: fmt.Sprintf("%s/slash_%s.db", dir, mode),
|
||||||
Version: version.GetCurrentVersion(mode),
|
Version: version.GetCurrentVersion(mode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
# Shortify
|
# Slash
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<link rel="icon" href="/logo.png" type="image/*" />
|
<link rel="icon" href="/logo.png" type="image/*" />
|
||||||
<meta name="theme-color" content="#FFFFFF" />
|
<meta name="theme-color" content="#FFFFFF" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
||||||
<title>Shortify</title>
|
<title>Slash</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "shortify",
|
"name": "slash",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
|
@ -19,12 +19,12 @@ const AboutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="max-w-full w-80 sm:w-96">
|
<div className="max-w-full w-80 sm:w-96">
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Shortify</span> is a bookmarking and short link service that allows you to save and share links
|
<span className="font-medium">Slash</span> is a bookmarking and short link service that allows you to save and share links
|
||||||
easily.
|
easily.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-1">
|
<div className="mt-1">
|
||||||
<span className="mr-2">See more in:</span>
|
<span className="mr-2">See more in:</span>
|
||||||
<Link variant="plain" href="https://github.com/boojack/shortify">
|
<Link variant="plain" href="https://github.com/boojack/slash">
|
||||||
GitHub
|
GitHub
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,7 @@ interface Props {
|
|||||||
const GenerateQRCodeDialog: React.FC<Props> = (props: Props) => {
|
const GenerateQRCodeDialog: React.FC<Props> = (props: Props) => {
|
||||||
const { shortcut, onClose } = props;
|
const { shortcut, onClose } = props;
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
const shortifyLink = absolutifyLink(`/s/${shortcut.name}`);
|
const shortcutLink = absolutifyLink(`/s/${shortcut.name}`);
|
||||||
|
|
||||||
const handleCloseBtnClick = () => {
|
const handleCloseBtnClick = () => {
|
||||||
onClose();
|
onClose();
|
||||||
@ -44,7 +44,7 @@ const GenerateQRCodeDialog: React.FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div ref={containerRef} className="w-full flex flex-row justify-center items-center mt-2 mb-6">
|
<div ref={containerRef} className="w-full flex flex-row justify-center items-center mt-2 mb-6">
|
||||||
<QRCodeCanvas value={shortifyLink} size={128} bgColor={"#ffffff"} fgColor={"#000000"} includeMargin={false} level={"L"} />
|
<QRCodeCanvas value={shortcutLink} size={128} bgColor={"#ffffff"} fgColor={"#000000"} includeMargin={false} level={"L"} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-center items-center px-4">
|
<div className="w-full flex flex-row justify-center items-center px-4">
|
||||||
<Button className="w-full" color="neutral" onClick={handleDownloadQRCodeClick}>
|
<Button className="w-full" color="neutral" onClick={handleDownloadQRCodeClick}>
|
||||||
|
@ -24,7 +24,7 @@ const Header: React.FC = () => {
|
|||||||
<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-base font-mono font-medium cursor-pointer flex flex-row justify-start items-center">
|
<Link to="/" className="text-base font-mono font-medium cursor-pointer flex flex-row justify-start items-center">
|
||||||
<img src="/logo.png" className="w-8 h-auto mr-2" alt="" />
|
<img src="/logo.png" className="w-8 h-auto mr-2" alt="" />
|
||||||
Shortify
|
Slash
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative flex-shrink-0">
|
<div className="relative flex-shrink-0">
|
||||||
|
@ -30,7 +30,7 @@ const ShortcutView = (props: Props) => {
|
|||||||
const [showQRCodeDialog, setShowQRCodeDialog] = useState<boolean>(false);
|
const [showQRCodeDialog, setShowQRCodeDialog] = useState<boolean>(false);
|
||||||
const [showAnalyticsDialog, setShowAnalyticsDialog] = useState<boolean>(false);
|
const [showAnalyticsDialog, setShowAnalyticsDialog] = useState<boolean>(false);
|
||||||
const havePermission = currentUser.role === "ADMIN" || shortcut.creatorId === currentUser.id;
|
const havePermission = currentUser.role === "ADMIN" || shortcut.creatorId === currentUser.id;
|
||||||
const shortifyLink = absolutifyLink(`/s/${shortcut.name}`);
|
const shortcutLink = absolutifyLink(`/s/${shortcut.name}`);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
faviconStore.getOrFetchUrlFavicon(shortcut.link).then((url) => {
|
faviconStore.getOrFetchUrlFavicon(shortcut.link).then((url) => {
|
||||||
@ -41,7 +41,7 @@ const ShortcutView = (props: Props) => {
|
|||||||
}, [shortcut.link]);
|
}, [shortcut.link]);
|
||||||
|
|
||||||
const handleCopyButtonClick = () => {
|
const handleCopyButtonClick = () => {
|
||||||
copy(shortifyLink);
|
copy(shortcutLink);
|
||||||
toast.success("Shortcut link copied to clipboard.");
|
toast.success("Shortcut link copied to clipboard.");
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ const ShortcutView = (props: Props) => {
|
|||||||
<a
|
<a
|
||||||
className="flex flex-row px-1 mr-1 justify-start items-center cursor-pointer rounded-md hover:bg-gray-100 hover:shadow"
|
className="flex flex-row px-1 mr-1 justify-start items-center cursor-pointer rounded-md hover:bg-gray-100 hover:shadow"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href={shortifyLink}
|
href={shortcutLink}
|
||||||
>
|
>
|
||||||
<span className="text-gray-400">s/</span>
|
<span className="text-gray-400">s/</span>
|
||||||
{shortcut.name}
|
{shortcut.name}
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
"visibility": {
|
"visibility": {
|
||||||
"private": {
|
"private": {
|
||||||
"self": "Private",
|
"self": "Private",
|
||||||
"description": "Only you can view this shortcut"
|
"description": "Only you can access"
|
||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"self": "Workspace",
|
"self": "Workspace",
|
||||||
"description": "Visible to Workspace Members"
|
"description": "Workspace members can access"
|
||||||
},
|
},
|
||||||
"public": {
|
"public": {
|
||||||
"self": "Public",
|
"self": "Public",
|
||||||
"description": "Visible to Everyone on the Internet"
|
"description": "Available to Everyone on the Internet"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ const SignIn: React.FC = () => {
|
|||||||
<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-col justify-start items-center w-full gap-y-2 mb-4">
|
<div className="flex flex-col justify-start items-center w-full gap-y-2 mb-4">
|
||||||
<img src="/logo.png" className="w-16 h-auto" alt="logo" />
|
<img src="/logo.png" className="w-16 h-auto" alt="logo" />
|
||||||
<span className="text-2xl font-medium font-mono opacity-80">Shortify</span>
|
<span className="text-2xl font-medium font-mono opacity-80">Slash</span>
|
||||||
</div>
|
</div>
|
||||||
<form className="w-full" onSubmit={handleSigninBtnClick}>
|
<form className="w-full" onSubmit={handleSigninBtnClick}>
|
||||||
<div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}>
|
<div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}>
|
||||||
@ -75,7 +75,7 @@ const SignIn: React.FC = () => {
|
|||||||
className="w-full py-3"
|
className="w-full py-3"
|
||||||
type="email"
|
type="email"
|
||||||
value={email}
|
value={email}
|
||||||
placeholder="steven@shortify.com"
|
placeholder="steven@slash.com"
|
||||||
onChange={handleEmailInputChanged}
|
onChange={handleEmailInputChanged}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -77,7 +77,7 @@ const SignUp: React.FC = () => {
|
|||||||
<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-col justify-start items-center w-full gap-y-2 mb-4">
|
<div className="flex flex-col justify-start items-center w-full gap-y-2 mb-4">
|
||||||
<img src="/logo.png" className="w-16 h-auto" alt="logo" />
|
<img src="/logo.png" className="w-16 h-auto" alt="logo" />
|
||||||
<span className="text-2xl font-medium font-mono opacity-80">Shortify</span>
|
<span className="text-2xl font-medium font-mono opacity-80">Slash</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="w-full text-center mb-4 text-2xl">Create your account</p>
|
<p className="w-full text-center mb-4 text-2xl">Create your account</p>
|
||||||
<form className="w-full" onSubmit={handleSignupBtnClick}>
|
<form className="w-full" onSubmit={handleSignupBtnClick}>
|
||||||
@ -88,7 +88,7 @@ const SignUp: React.FC = () => {
|
|||||||
className="w-full py-3"
|
className="w-full py-3"
|
||||||
type="email"
|
type="email"
|
||||||
value={email}
|
value={email}
|
||||||
placeholder="steven@shortify.com"
|
placeholder="steven@slash.com"
|
||||||
onChange={handleEmailInputChanged}
|
onChange={handleEmailInputChanged}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user