mirror of
https://github.com/chenasraf/stimvisor.git
synced 2026-05-17 17:38:11 +00:00
feat: nunito, wip steam lib meta data
This commit is contained in:
54
app.go
54
app.go
@@ -2,7 +2,8 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// App struct
|
||||
@@ -21,22 +22,49 @@ func (a *App) startup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
}
|
||||
|
||||
func JsonResponse(data interface{}, err error) string {
|
||||
if err != nil {
|
||||
res, _ := json.Marshal(map[string]interface{}{"error": err.Error()})
|
||||
return string(res)
|
||||
}
|
||||
res, _ := json.Marshal(data)
|
||||
return string(res)
|
||||
func WrapError(err error) SteamLibraryMeta {
|
||||
return SteamLibraryMeta{Error: err.Error()}
|
||||
}
|
||||
|
||||
func (a *App) GetScreenshotsDirs() string {
|
||||
type SteamLibraryMeta struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
SteamDir string `json:"steamDir"`
|
||||
UserDir string `json:"userDir"`
|
||||
GameDirs []string `json:"gameDirs"`
|
||||
ScreenshotsDirs []string `json:"screenshotsDirs"`
|
||||
SyncDir string `json:"syncDir"`
|
||||
}
|
||||
|
||||
func (a *App) GetSteamLibraryMeta() SteamLibraryMeta {
|
||||
p, err := GetSteamDirectory()
|
||||
if err != nil {
|
||||
return JsonResponse(nil, err)
|
||||
return WrapError(err)
|
||||
}
|
||||
userDir, err := GetSteamUserDirectory()
|
||||
if err != nil {
|
||||
return WrapError(err)
|
||||
}
|
||||
fmt.Printf("User Dir: %s\n", userDir)
|
||||
userId := filepath.Base(userDir)
|
||||
gd, err := GetGameDirectories(userId)
|
||||
if err != nil {
|
||||
return WrapError(err)
|
||||
}
|
||||
syncDir, err := GetSyncDirectory()
|
||||
if err != nil {
|
||||
return WrapError(err)
|
||||
}
|
||||
screenshotsDirs, err := GetScreenshotsDirs()
|
||||
if err != nil {
|
||||
return WrapError(err)
|
||||
}
|
||||
out := SteamLibraryMeta{
|
||||
SteamDir: p,
|
||||
GameDirs: gd,
|
||||
UserDir: userDir,
|
||||
SyncDir: syncDir,
|
||||
ScreenshotsDirs: screenshotsDirs,
|
||||
}
|
||||
out := make(map[string]interface{})
|
||||
out["steamDir"] = p
|
||||
|
||||
return JsonResponse(out, nil)
|
||||
return out
|
||||
}
|
||||
|
||||
85
dirs.go
85
dirs.go
@@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -42,24 +44,30 @@ func GetSteamDirectory() (string, error) {
|
||||
return fmt.Sprintf(format, homedir), nil
|
||||
}
|
||||
|
||||
func GetSteamUserdataDirectory() (string, error) {
|
||||
steamDir, err := GetSteamDirectory()
|
||||
func GetSteamUserDirectory() (string, error) {
|
||||
userDirs, err := GetUsersDirectories()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%s/userdata", steamDir), nil
|
||||
if len(userDirs) == 0 {
|
||||
return "", fmt.Errorf("Could not find any Steam users")
|
||||
}
|
||||
// TODO multiple users
|
||||
return userDirs[0], nil
|
||||
}
|
||||
|
||||
func GetSyncDirectory() (string, error) {
|
||||
dataDir, err := GetSteamUserdataDirectory()
|
||||
userDir, err := GetSteamUserDirectory()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%s/760", dataDir), nil
|
||||
return fmt.Sprintf("%s/760", userDir), nil
|
||||
}
|
||||
|
||||
var STEAM_INTERNAL_IDS = []string{"7", "760"}
|
||||
|
||||
// screenshots: /Users/chen/Library/Application\ Support/Steam/userdata/37889173/760/remote/1086940/screenshots
|
||||
func GetGameDirectories() ([]string, error) {
|
||||
func GetUsersDirectories() ([]string, error) {
|
||||
steamDir, err := GetSteamDirectory()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -69,13 +77,76 @@ func GetGameDirectories() ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var gameDirs []string
|
||||
var userDirs []string
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
gameDir := fmt.Sprintf("%s/%s", steamUserData, entry.Name())
|
||||
userDirs = append(userDirs, gameDir)
|
||||
}
|
||||
return userDirs, nil
|
||||
}
|
||||
|
||||
func GetUserDirectory(userId string) (string, error) {
|
||||
steamDir, err := GetSteamDirectory()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fmt.Printf("Get User Dir: %s/userdata/%s\n", steamDir, userId)
|
||||
return fmt.Sprintf("%s/userdata/%s", steamDir, userId), nil
|
||||
}
|
||||
|
||||
func GetGameDirectories(userId string) ([]string, error) {
|
||||
userDir, err := GetUserDirectory(userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entries, err := os.ReadDir(userDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gameDirs := []string{}
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
if slices.Contains(STEAM_INTERNAL_IDS, entry.Name()) {
|
||||
continue
|
||||
}
|
||||
if _, err := strconv.Atoi(entry.Name()); err != nil {
|
||||
continue
|
||||
}
|
||||
gameDir := fmt.Sprintf("%s/%s", userDir, entry.Name())
|
||||
gameDirs = append(gameDirs, gameDir)
|
||||
}
|
||||
return gameDirs, nil
|
||||
}
|
||||
|
||||
func GetScreenshotsDirs() ([]string, error) {
|
||||
syncDir, err := GetSyncDirectory()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var dirs []string
|
||||
remoteDir := fmt.Sprintf("%s/remote", syncDir)
|
||||
entries, err := os.ReadDir(remoteDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, entry := range entries {
|
||||
fmt.Printf("Entry: %s\n", entry.Name())
|
||||
if !entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
scrDir := fmt.Sprintf("%s/%s/screenshots", remoteDir, entry.Name())
|
||||
fmt.Printf("Checking: %s\n", scrDir)
|
||||
if _, err := os.Stat(scrDir); os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
dirs = append(dirs, scrDir)
|
||||
}
|
||||
return dirs, nil
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
||||
<title>stimvisor</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="./src/main.tsx" type="module"></script>
|
||||
</body>
|
||||
</head>
|
||||
<body class="font-nunito">
|
||||
<div id="root"></div>
|
||||
<script src="./src/main.tsx" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -11,8 +11,10 @@
|
||||
"dependencies": {
|
||||
"@fontsource-variable/nunito": "^5.1.0",
|
||||
"@tanstack/react-query": "^5.59.15",
|
||||
"clsx": "^2.1.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
"react-dom": "^18.3.1",
|
||||
"tailwind-merge": "^2.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.12.0",
|
||||
|
||||
@@ -1 +1 @@
|
||||
1e8656145625684f371b8ed4aff2036d
|
||||
a2816a52857b069ddfc7f6d2622f2c9d
|
||||
17
frontend/pnpm-lock.yaml
generated
17
frontend/pnpm-lock.yaml
generated
@@ -14,12 +14,18 @@ importers:
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.59.15
|
||||
version: 5.59.15(react@18.3.1)
|
||||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
react:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1
|
||||
react-dom:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1(react@18.3.1)
|
||||
tailwind-merge:
|
||||
specifier: ^2.5.4
|
||||
version: 2.5.4
|
||||
devDependencies:
|
||||
'@eslint/js':
|
||||
specifier: ^9.12.0
|
||||
@@ -725,6 +731,10 @@ packages:
|
||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||
engines: {node: '>= 8.10.0'}
|
||||
|
||||
clsx@2.1.1:
|
||||
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
color-convert@1.9.3:
|
||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||
|
||||
@@ -1313,6 +1323,9 @@ packages:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
tailwind-merge@2.5.4:
|
||||
resolution: {integrity: sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==}
|
||||
|
||||
tailwindcss@3.4.14:
|
||||
resolution: {integrity: sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@@ -2057,6 +2070,8 @@ snapshots:
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
clsx@2.1.1: {}
|
||||
|
||||
color-convert@1.9.3:
|
||||
dependencies:
|
||||
color-name: 1.1.3
|
||||
@@ -2618,6 +2633,8 @@ snapshots:
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0: {}
|
||||
|
||||
tailwind-merge@2.5.4: {}
|
||||
|
||||
tailwindcss@3.4.14:
|
||||
dependencies:
|
||||
'@alloc/quick-lru': 5.2.0
|
||||
|
||||
@@ -5,11 +5,12 @@ import { useState } from 'react'
|
||||
function App() {
|
||||
const [queryClient] = useState(() => new QueryClient())
|
||||
return (
|
||||
<div id="App" className="bg-bg min-h-screen text-gray-400">
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Sidebar />
|
||||
</QueryClientProvider>
|
||||
</div>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<div id="App" className="min-h-screen flex">
|
||||
<Sidebar className="w-64" />
|
||||
<div />
|
||||
</div>
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
BIN
frontend/src/assets/fonts/nunito-cyrillic-ext-wght-italic.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-cyrillic-ext-wght-italic.woff2
Normal file
Binary file not shown.
BIN
frontend/src/assets/fonts/nunito-cyrillic-ext-wght-normal.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-cyrillic-ext-wght-normal.woff2
Normal file
Binary file not shown.
BIN
frontend/src/assets/fonts/nunito-cyrillic-wght-italic.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-cyrillic-wght-italic.woff2
Normal file
Binary file not shown.
BIN
frontend/src/assets/fonts/nunito-cyrillic-wght-normal.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-cyrillic-wght-normal.woff2
Normal file
Binary file not shown.
BIN
frontend/src/assets/fonts/nunito-latin-ext-wght-italic.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-latin-ext-wght-italic.woff2
Normal file
Binary file not shown.
BIN
frontend/src/assets/fonts/nunito-latin-ext-wght-normal.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-latin-ext-wght-normal.woff2
Normal file
Binary file not shown.
BIN
frontend/src/assets/fonts/nunito-latin-wght-italic.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-latin-wght-italic.woff2
Normal file
Binary file not shown.
BIN
frontend/src/assets/fonts/nunito-latin-wght-normal.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-latin-wght-normal.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
frontend/src/assets/fonts/nunito-vietnamese-wght-italic.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-vietnamese-wght-italic.woff2
Normal file
Binary file not shown.
BIN
frontend/src/assets/fonts/nunito-vietnamese-wght-normal.woff2
Normal file
BIN
frontend/src/assets/fonts/nunito-vietnamese-wght-normal.woff2
Normal file
Binary file not shown.
@@ -7,17 +7,30 @@ type FullfilledUseQueryResult<TData = unknown, TError = Error> = Omit<
|
||||
data: Exclude<TData, undefined>
|
||||
}
|
||||
|
||||
type WrappedUseQueryOptions<TData, TError, TQueryFnData> = UseQueryOptions<
|
||||
TQueryFnData,
|
||||
TError,
|
||||
TData
|
||||
> & { debug?: boolean }
|
||||
|
||||
export function useApi<T>(
|
||||
promise: () => Promise<unknown>,
|
||||
options: Partial<UseQueryOptions<unknown, Error, T>> = {},
|
||||
promise: () => Promise<T>,
|
||||
options: Partial<WrappedUseQueryOptions<T, Error, T>> = {},
|
||||
): FullfilledUseQueryResult<T, Error> {
|
||||
const query = useQuery({
|
||||
queryFn: () =>
|
||||
promise()
|
||||
.then((result) => JSON.parse(result as string))
|
||||
.then((json) => (json.error ? Promise.reject(json.error) : Promise.resolve(json))),
|
||||
queryFn: async () => {
|
||||
if (options.debug) console.debug('useApi', promise)
|
||||
const json = await promise()
|
||||
if (options.debug) console.debug('useApi response:', json)
|
||||
return await (isError(json) ? Promise.reject(json.error) : Promise.resolve(json))
|
||||
},
|
||||
queryKey: [],
|
||||
...options,
|
||||
})
|
||||
return query as FullfilledUseQueryResult<T, Error>
|
||||
}
|
||||
|
||||
function isError(json: unknown): json is { error: unknown } {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return Boolean((json as any).error)
|
||||
}
|
||||
|
||||
1
frontend/src/common/types.ts
Normal file
1
frontend/src/common/types.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type HtmlProps<T extends keyof JSX.IntrinsicElements> = JSX.IntrinsicElements[T]
|
||||
5
frontend/src/common/utils.ts
Normal file
5
frontend/src/common/utils.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import clsx, { ClassValue } from 'clsx'
|
||||
export function cn(...classes: ClassValue[]): string {
|
||||
return twMerge(clsx(...classes))
|
||||
}
|
||||
@@ -1,34 +1,38 @@
|
||||
import { useApi } from '../../common/api'
|
||||
import { GetScreenshotsDirs } from '../../../wailsjs/go/main/App'
|
||||
import { GetSteamLibraryMeta } from '../../../wailsjs/go/main/App'
|
||||
import { HtmlProps } from '../../common/types'
|
||||
import React from 'react'
|
||||
import { cn } from '../../common/utils'
|
||||
|
||||
export function Sidebar() {
|
||||
const { data } = useApi<{ steamDir: string }>(() => GetScreenshotsDirs(), { initialData: {} })
|
||||
export function Sidebar({ className, ...rest }: HtmlProps<'div'>) {
|
||||
const { data } = useApi(() => GetSteamLibraryMeta(), { initialData: {} as never, debug: true })
|
||||
const { steamDir } = data
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ul className="my-3">
|
||||
<ListItem>Games</ListItem>
|
||||
<ListItem>
|
||||
<div>Screenshots</div>
|
||||
<ul>
|
||||
{[steamDir].map((item, i) => (
|
||||
<ListItem key={i} data-key={item}>
|
||||
{item}
|
||||
</ListItem>
|
||||
))}
|
||||
</ul>
|
||||
</ListItem>
|
||||
<ListItem>Save Data</ListItem>
|
||||
<div className={cn('py-3 bg-bg-800 h-screen overflow-y-auto', className)} {...rest}>
|
||||
<ul>
|
||||
<ListItem label="Games" />
|
||||
<ListItem label="Screenshots" />
|
||||
<ListItem label="Save Data" />
|
||||
</ul>
|
||||
<code>
|
||||
<pre>{JSON.stringify(data, null, 2)}</pre>
|
||||
</code>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ListItem({ children }: React.PropsWithChildren<object>) {
|
||||
function ListItem({ children, label, ...rest }: HtmlProps<'div'> & { label: React.ReactNode }) {
|
||||
// TODO should be siblings under a fragment, use li instead of div for props ^
|
||||
return (
|
||||
<li className="h-10 flex items-center justify-start py-3 px-6 hover:bg-bg-800 cursor-pointer">
|
||||
{children}
|
||||
<li>
|
||||
<div
|
||||
className="min-h-10 flex items-center justify-start py-3 px-6 hover:bg-bg-700 cursor-pointer"
|
||||
{...rest}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
{children ? <ul>{children}</ul> : null}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
53
frontend/src/fonts.css
Normal file
53
frontend/src/fonts.css
Normal file
@@ -0,0 +1,53 @@
|
||||
/* nunito-cyrillic-ext-wght-normal */
|
||||
@font-face {
|
||||
font-family: 'Nunito Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 200 1000;
|
||||
src: url(fonts/nunito-cyrillic-ext-wght-normal.woff2) format('woff2-variations');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
|
||||
/* nunito-cyrillic-wght-normal */
|
||||
@font-face {
|
||||
font-family: 'Nunito Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 200 1000;
|
||||
src: url(fonts/nunito-cyrillic-wght-normal.woff2) format('woff2-variations');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
|
||||
/* nunito-vietnamese-wght-normal */
|
||||
@font-face {
|
||||
font-family: 'Nunito Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 200 1000;
|
||||
src: url(fonts/nunito-vietnamese-wght-normal.woff2) format('woff2-variations');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0,
|
||||
U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
|
||||
/* nunito-latin-ext-wght-normal */
|
||||
@font-face {
|
||||
font-family: 'Nunito Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 200 1000;
|
||||
src: url(fonts/nunito-latin-ext-wght-normal.woff2) format('woff2-variations');
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
|
||||
U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
/* nunito-latin-wght-normal */
|
||||
@font-face {
|
||||
font-family: 'Nunito Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 200 1000;
|
||||
src: url(fonts/nunito-latin-wght-normal.woff2) format('woff2-variations');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
|
||||
U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF,
|
||||
U+FFFD;
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import React from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './style.css'
|
||||
import '@fontsource-variable/nunito'
|
||||
// import './fonts.css'
|
||||
import './reset.css'
|
||||
import './style.css'
|
||||
import App from './App'
|
||||
|
||||
const container = document.getElementById('root')
|
||||
|
||||
135
frontend/src/reset.css
Normal file
135
frontend/src/reset.css
Normal file
@@ -0,0 +1,135 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
span,
|
||||
applet,
|
||||
object,
|
||||
iframe,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
blockquote,
|
||||
pre,
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
big,
|
||||
cite,
|
||||
code,
|
||||
del,
|
||||
dfn,
|
||||
em,
|
||||
img,
|
||||
ins,
|
||||
kbd,
|
||||
q,
|
||||
s,
|
||||
samp,
|
||||
small,
|
||||
strike,
|
||||
strong,
|
||||
sub,
|
||||
sup,
|
||||
tt,
|
||||
var,
|
||||
b,
|
||||
u,
|
||||
i,
|
||||
center,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ol,
|
||||
ul,
|
||||
li,
|
||||
fieldset,
|
||||
form,
|
||||
label,
|
||||
legend,
|
||||
table,
|
||||
caption,
|
||||
tbody,
|
||||
tfoot,
|
||||
thead,
|
||||
tr,
|
||||
th,
|
||||
td,
|
||||
article,
|
||||
aside,
|
||||
canvas,
|
||||
details,
|
||||
embed,
|
||||
figure,
|
||||
figcaption,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
output,
|
||||
ruby,
|
||||
section,
|
||||
summary,
|
||||
time,
|
||||
mark,
|
||||
audio,
|
||||
video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
blockquote,
|
||||
q {
|
||||
quotes: none;
|
||||
}
|
||||
|
||||
blockquote:before,
|
||||
blockquote:after,
|
||||
q:before,
|
||||
q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
@@ -4,159 +4,14 @@
|
||||
|
||||
html {
|
||||
@apply bg-bg;
|
||||
color: white;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
color: white;
|
||||
font-family:
|
||||
'Nunito Variable',
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
'Helvetica Neue',
|
||||
'Segoe UI',
|
||||
'Roboto',
|
||||
'Oxygen',
|
||||
'Ubuntu',
|
||||
'Cantarell',
|
||||
'Fira Sans',
|
||||
'Droid Sans',
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
/* body { */
|
||||
/* min-height: 100vh; */
|
||||
/* } */
|
||||
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
span,
|
||||
applet,
|
||||
object,
|
||||
iframe,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
blockquote,
|
||||
pre,
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
big,
|
||||
cite,
|
||||
code,
|
||||
del,
|
||||
dfn,
|
||||
em,
|
||||
img,
|
||||
ins,
|
||||
kbd,
|
||||
q,
|
||||
s,
|
||||
samp,
|
||||
small,
|
||||
strike,
|
||||
strong,
|
||||
sub,
|
||||
sup,
|
||||
tt,
|
||||
var,
|
||||
b,
|
||||
u,
|
||||
i,
|
||||
center,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ol,
|
||||
ul,
|
||||
li,
|
||||
fieldset,
|
||||
form,
|
||||
label,
|
||||
legend,
|
||||
table,
|
||||
caption,
|
||||
tbody,
|
||||
tfoot,
|
||||
thead,
|
||||
tr,
|
||||
th,
|
||||
td,
|
||||
article,
|
||||
aside,
|
||||
canvas,
|
||||
details,
|
||||
embed,
|
||||
figure,
|
||||
figcaption,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
output,
|
||||
ruby,
|
||||
section,
|
||||
summary,
|
||||
time,
|
||||
mark,
|
||||
audio,
|
||||
video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
blockquote,
|
||||
q {
|
||||
quotes: none;
|
||||
}
|
||||
|
||||
blockquote:before,
|
||||
blockquote:after,
|
||||
q:before,
|
||||
q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
@apply text-gray-400;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,22 @@ export default {
|
||||
...colors,
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
nunito: [
|
||||
'Nunito Variable',
|
||||
'-apple-system',
|
||||
'BlinkMacSystemFont',
|
||||
'Helvetica Neue',
|
||||
'Segoe UI',
|
||||
'Roboto',
|
||||
'Oxygen',
|
||||
'Ubuntu',
|
||||
'Cantarell',
|
||||
'Fira Sans',
|
||||
'Droid Sans',
|
||||
'sans-serif',
|
||||
],
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
3
frontend/wailsjs/go/main/App.d.ts
vendored
3
frontend/wailsjs/go/main/App.d.ts
vendored
@@ -1,4 +1,5 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
import {main} from '../models';
|
||||
|
||||
export function GetScreenshotsDirs():Promise<string>;
|
||||
export function GetSteamLibraryMeta():Promise<main.SteamLibraryMeta>;
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export function GetScreenshotsDirs() {
|
||||
return window['go']['main']['App']['GetScreenshotsDirs']();
|
||||
export function GetSteamLibraryMeta() {
|
||||
return window['go']['main']['App']['GetSteamLibraryMeta']();
|
||||
}
|
||||
|
||||
27
frontend/wailsjs/go/models.ts
Executable file
27
frontend/wailsjs/go/models.ts
Executable file
@@ -0,0 +1,27 @@
|
||||
export namespace main {
|
||||
|
||||
export class SteamLibraryMeta {
|
||||
error?: string;
|
||||
steamDir: string;
|
||||
userDir: string;
|
||||
gameDirs: string[];
|
||||
screenshotsDirs: string[];
|
||||
syncDir: string;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new SteamLibraryMeta(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.error = source["error"];
|
||||
this.steamDir = source["steamDir"];
|
||||
this.userDir = source["userDir"];
|
||||
this.gameDirs = source["gameDirs"];
|
||||
this.screenshotsDirs = source["screenshotsDirs"];
|
||||
this.syncDir = source["syncDir"];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
43
invoke.go
43
invoke.go
@@ -1,43 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Invoke struct {
|
||||
Command string
|
||||
}
|
||||
|
||||
type InvokeRunnable interface {
|
||||
Run(args map[string]interface{})
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
type GetScreenshotsDirs struct {
|
||||
Command string
|
||||
}
|
||||
|
||||
func (g GetScreenshotsDirs) Run(args map[string]interface{}) {
|
||||
p, err := GetSteamDirectory()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
out := make(map[string]interface{})
|
||||
out["steam_dir"] = p
|
||||
|
||||
res, _ := json.Marshal(out)
|
||||
fmt.Println(string(res))
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
func parseCommand(command string) (InvokeRunnable, error) {
|
||||
switch command {
|
||||
case "get_screenshots_dirs":
|
||||
return GetScreenshotsDirs{}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unknown command %q", command)
|
||||
}
|
||||
Reference in New Issue
Block a user