mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-22 16:07:49 +08:00
Update On Sat Jan 10 19:39:32 CET 2026
This commit is contained in:
@@ -1238,3 +1238,4 @@ Update On Tue Jan 6 19:44:08 CET 2026
|
||||
Update On Wed Jan 7 19:44:04 CET 2026
|
||||
Update On Thu Jan 8 19:40:15 CET 2026
|
||||
Update On Fri Jan 9 19:44:47 CET 2026
|
||||
Update On Sat Jan 10 19:39:24 CET 2026
|
||||
|
||||
@@ -18,7 +18,27 @@ public class MediaListFetcher : IFetcher
|
||||
var api = $"https://api.bilibili.com/x/v1/medialist/info?type=8&biz_id={id}&tid=0";
|
||||
var json = await GetWebSourceAsync(api);
|
||||
using var infoJson = JsonDocument.Parse(json);
|
||||
var data = infoJson.RootElement.GetProperty("data");
|
||||
var root = infoJson.RootElement;
|
||||
var data = root.GetProperty("data");
|
||||
if (data.ValueKind != JsonValueKind.Object)
|
||||
{
|
||||
// 部分情况下(合集被删除、设为私密或无权访问)data 会是 null
|
||||
// 也有可能是“系列”却被误识别为合集,这里优先尝试按系列解析
|
||||
try
|
||||
{
|
||||
return await new SeriesListFetcher().FetchAsync($"seriesBizId:{id}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
var code = root.TryGetProperty("code", out var codeElem) && codeElem.ValueKind == JsonValueKind.Number
|
||||
? codeElem.GetInt32()
|
||||
: 0;
|
||||
var message = root.TryGetProperty("message", out var msgElem) && msgElem.ValueKind == JsonValueKind.String
|
||||
? msgElem.GetString()
|
||||
: "未知错误";
|
||||
throw new Exception($"获取合集信息失败(code={code}): {message}");
|
||||
}
|
||||
}
|
||||
var listTitle = data.GetProperty("title").GetString()!;
|
||||
var intro = data.GetProperty("intro").GetString()!;
|
||||
long pubTime = data.GetProperty("ctime").GetInt64()!;
|
||||
@@ -32,10 +52,25 @@ public class MediaListFetcher : IFetcher
|
||||
var listApi = $"https://api.bilibili.com/x/v2/medialist/resource/list?type=8&oid={oid}&otype=2&biz_id={id}&with_current=true&mobi_app=web&ps=20&direction=false&sort_field=1&tid=0&desc=false";
|
||||
json = await GetWebSourceAsync(listApi);
|
||||
using var listJson = JsonDocument.Parse(json);
|
||||
data = listJson.RootElement.GetProperty("data");
|
||||
var listRoot = listJson.RootElement;
|
||||
data = listRoot.GetProperty("data");
|
||||
if (data.ValueKind != JsonValueKind.Object)
|
||||
{
|
||||
var code = listRoot.TryGetProperty("code", out var codeElem) && codeElem.ValueKind == JsonValueKind.Number
|
||||
? codeElem.GetInt32()
|
||||
: 0;
|
||||
var message = listRoot.TryGetProperty("message", out var msgElem) && msgElem.ValueKind == JsonValueKind.String
|
||||
? msgElem.GetString()
|
||||
: "未知错误";
|
||||
throw new Exception($"获取合集视频列表失败(code={code}): {message}");
|
||||
}
|
||||
hasMore = data.GetProperty("has_more").GetBoolean();
|
||||
foreach (var m in data.GetProperty("media_list").EnumerateArray())
|
||||
{
|
||||
// 只处理未失效的视频条目(与收藏夹解析逻辑保持一致)
|
||||
if (m.TryGetProperty("attr", out var attrElem) && attrElem.GetInt32() != 0)
|
||||
continue;
|
||||
|
||||
var pageCount = m.GetProperty("page").GetInt32();
|
||||
var desc = m.GetProperty("intro").GetString()!;
|
||||
var ownerName = m.GetProperty("upper").GetProperty("name").ToString();
|
||||
|
||||
@@ -37,6 +37,10 @@ public class SeriesListFetcher : IFetcher
|
||||
hasMore = data.GetProperty("has_more").GetBoolean();
|
||||
foreach (var m in data.GetProperty("media_list").EnumerateArray())
|
||||
{
|
||||
// 只处理未失效的视频条目(与收藏夹解析逻辑保持一致)
|
||||
if (m.TryGetProperty("attr", out var attrElem) && attrElem.GetInt32() != 0)
|
||||
continue;
|
||||
|
||||
var pageCount = m.GetProperty("page").GetInt32();
|
||||
var desc = m.GetProperty("intro").GetString()!;
|
||||
var ownerName = m.GetProperty("upper").GetProperty("name").ToString();
|
||||
|
||||
@@ -100,6 +100,31 @@ static partial class BBDownUtil
|
||||
string bizId = GetQueryString("sid", input);
|
||||
avid = $"seriesBizId:{bizId}";
|
||||
}
|
||||
// 新版个人空间合集/系列链接兼容:
|
||||
// 例如:
|
||||
// 合集: https://space.bilibili.com/392959666/lists/1560264?type=season
|
||||
// 系列: https://space.bilibili.com/392959666/lists/1560264?type=series
|
||||
else if (input.Contains("/space.bilibili.com/") && input.Contains("/lists/"))
|
||||
{
|
||||
var type = GetQueryString("type", input).ToLower();
|
||||
// path 最后一个 / 后到 ? 前即为 sid
|
||||
var path = input.Split('?', '#')[0];
|
||||
var sidPart = path[(path.LastIndexOf('/') + 1)..];
|
||||
|
||||
if (type == "season")
|
||||
{
|
||||
avid = $"listBizId:{sidPart}";
|
||||
}
|
||||
else if (type == "series")
|
||||
{
|
||||
avid = $"seriesBizId:{sidPart}";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 未知类型按合集处理,至少不会识别失败
|
||||
avid = $"listBizId:{sidPart}";
|
||||
}
|
||||
}
|
||||
else if (input.Contains("/space.bilibili.com/") && input.Contains("/favlist"))
|
||||
{
|
||||
string mid = UidRegex().Match(input).Groups[1].Value;
|
||||
|
||||
@@ -422,11 +422,11 @@ export const commands = {
|
||||
else return { status: 'error', error: e as any }
|
||||
}
|
||||
},
|
||||
async saveWindowSizeState(): Promise<Result<null, string>> {
|
||||
async saveMainWindowSizeState(): Promise<Result<null, string>> {
|
||||
try {
|
||||
return {
|
||||
status: 'ok',
|
||||
data: await TAURI_INVOKE('save_window_size_state'),
|
||||
data: await TAURI_INVOKE('save_main_window_size_state'),
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof Error) throw e
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
PushPinOutlined,
|
||||
} from '@mui/icons-material'
|
||||
import { Button, ButtonProps } from '@mui/material'
|
||||
import { saveWindowSizeState, useSetting } from '@nyanpasu/interface'
|
||||
import { commands, useSetting } from '@nyanpasu/interface'
|
||||
import { alpha, cn } from '@nyanpasu/ui'
|
||||
import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query'
|
||||
import { listen, TauriEvent, UnlistenFn } from '@tauri-apps/api/event'
|
||||
@@ -98,7 +98,7 @@ export const LayoutControl = ({ className }: { className?: string }) => {
|
||||
<CtrlButton
|
||||
onClick={() => {
|
||||
if (platform.current === 'windows') {
|
||||
saveWindowSizeState().finally(() => {
|
||||
commands.saveMainWindowSizeState().finally(() => {
|
||||
appWindow.close()
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { cn } from '@nyanpasu/ui'
|
||||
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area'
|
||||
|
||||
interface ScrollAreaContextValue {
|
||||
isScrolling: boolean
|
||||
isTop: boolean
|
||||
isBottom: boolean
|
||||
scrollDirection: 'up' | 'down' | 'left' | 'right' | 'none'
|
||||
@@ -23,6 +24,7 @@ export function useScrollArea() {
|
||||
}
|
||||
|
||||
function useScrollTracking(threshold = 50) {
|
||||
const [isScrolling, setIsScrolling] = useState(false)
|
||||
const [isTop, setIsTop] = useState(true)
|
||||
const [isBottom, setIsBottom] = useState(false)
|
||||
const [scrollDirection, setScrollDirection] = useState<
|
||||
@@ -32,10 +34,18 @@ function useScrollTracking(threshold = 50) {
|
||||
const lastScrollTop = useRef(0)
|
||||
const lastScrollLeft = useRef(0)
|
||||
|
||||
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
|
||||
const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
||||
const target = e.currentTarget as HTMLElement
|
||||
const { scrollTop, scrollLeft, scrollHeight, clientHeight } = target
|
||||
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current)
|
||||
}
|
||||
|
||||
setIsScrolling(true)
|
||||
|
||||
setIsTop(scrollTop === 0)
|
||||
|
||||
// check if is at bottom, allow a small threshold
|
||||
@@ -62,9 +72,17 @@ function useScrollTracking(threshold = 50) {
|
||||
|
||||
lastScrollTop.current = scrollTop
|
||||
lastScrollLeft.current = scrollLeft
|
||||
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current)
|
||||
}
|
||||
|
||||
setIsScrolling(false)
|
||||
}, threshold)
|
||||
}
|
||||
|
||||
return { isTop, isBottom, scrollDirection, handleScroll }
|
||||
return { isTop, isBottom, scrollDirection, handleScroll, isScrolling }
|
||||
}
|
||||
|
||||
export function Viewport({
|
||||
@@ -151,11 +169,13 @@ export function AppContentScrollArea({
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
||||
const viewportRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const { isTop, isBottom, scrollDirection, handleScroll } = useScrollTracking()
|
||||
const { isTop, isBottom, scrollDirection, handleScroll, isScrolling } =
|
||||
useScrollTracking()
|
||||
|
||||
return (
|
||||
<ScrollAreaContext.Provider
|
||||
value={{
|
||||
isScrolling,
|
||||
isTop,
|
||||
isBottom,
|
||||
scrollDirection,
|
||||
@@ -175,6 +195,7 @@ export function AppContentScrollArea({
|
||||
data-slot="app-content-scroll-area"
|
||||
type="scroll"
|
||||
scrollHideDelay={600}
|
||||
data-scrolling={String(isScrolling)}
|
||||
data-top={String(isTop)}
|
||||
data-bottom={String(isBottom)}
|
||||
data-scroll-direction={scrollDirection}
|
||||
|
||||
@@ -2,6 +2,21 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
||||
|
||||
## [2.54.0](https://github.com/filebrowser/filebrowser/compare/v2.53.1...v2.54.0) (2026-01-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add "redirect after copy/move" user setting ([#5662](https://github.com/filebrowser/filebrowser/issues/5662)) ([fda8a99](https://github.com/filebrowser/filebrowser/commit/fda8a992929b1466e75fb2813f2c4e293c12d244))
|
||||
* force file sync while uploading file ([#5668](https://github.com/filebrowser/filebrowser/issues/5668)) ([4fd18a3](https://github.com/filebrowser/filebrowser/commit/4fd18a382c31bbe7059d6733ffa371e70051865b))
|
||||
* update translations ([#5659](https://github.com/filebrowser/filebrowser/issues/5659)) ([464b581](https://github.com/filebrowser/filebrowser/commit/464b581953139c17e3276b774e381e4052827125))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* clear selection by clicking on empty area ([#5663](https://github.com/filebrowser/filebrowser/issues/5663)) ([208535a](https://github.com/filebrowser/filebrowser/commit/208535a8cc23254de0013dfab9008486707ee6c2))
|
||||
* hide "change password form" in noauth setting ([#5652](https://github.com/filebrowser/filebrowser/issues/5652)) ([219582c](https://github.com/filebrowser/filebrowser/commit/219582c0b03fd90979b1d1398dba7919d086a23f))
|
||||
|
||||
## [2.53.1](https://github.com/filebrowser/filebrowser/compare/v2.53.0...v2.53.1) (2026-01-03)
|
||||
|
||||
|
||||
|
||||
+20
-17
@@ -158,16 +158,17 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
|
||||
|
||||
// create user with the provided credentials
|
||||
d := &users.User{
|
||||
Username: a.Cred.Username,
|
||||
Password: pass,
|
||||
Scope: a.Settings.Defaults.Scope,
|
||||
Locale: a.Settings.Defaults.Locale,
|
||||
ViewMode: a.Settings.Defaults.ViewMode,
|
||||
SingleClick: a.Settings.Defaults.SingleClick,
|
||||
Sorting: a.Settings.Defaults.Sorting,
|
||||
Perm: a.Settings.Defaults.Perm,
|
||||
Commands: a.Settings.Defaults.Commands,
|
||||
HideDotfiles: a.Settings.Defaults.HideDotfiles,
|
||||
Username: a.Cred.Username,
|
||||
Password: pass,
|
||||
Scope: a.Settings.Defaults.Scope,
|
||||
Locale: a.Settings.Defaults.Locale,
|
||||
ViewMode: a.Settings.Defaults.ViewMode,
|
||||
SingleClick: a.Settings.Defaults.SingleClick,
|
||||
RedirectAfterCopyMove: a.Settings.Defaults.RedirectAfterCopyMove,
|
||||
Sorting: a.Settings.Defaults.Sorting,
|
||||
Perm: a.Settings.Defaults.Perm,
|
||||
Commands: a.Settings.Defaults.Commands,
|
||||
HideDotfiles: a.Settings.Defaults.HideDotfiles,
|
||||
}
|
||||
u = a.GetUser(d)
|
||||
|
||||
@@ -219,13 +220,14 @@ func (a *HookAuth) GetUser(d *users.User) *users.User {
|
||||
Download: isAdmin || a.Fields.GetBoolean("user.perm.download", d.Perm.Download),
|
||||
}
|
||||
user := users.User{
|
||||
ID: d.ID,
|
||||
Username: d.Username,
|
||||
Password: d.Password,
|
||||
Scope: a.Fields.GetString("user.scope", d.Scope),
|
||||
Locale: a.Fields.GetString("user.locale", d.Locale),
|
||||
ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
|
||||
SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
|
||||
ID: d.ID,
|
||||
Username: d.Username,
|
||||
Password: d.Password,
|
||||
Scope: a.Fields.GetString("user.scope", d.Scope),
|
||||
Locale: a.Fields.GetString("user.locale", d.Locale),
|
||||
ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
|
||||
SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
|
||||
RedirectAfterCopyMove: a.Fields.GetBoolean("user.redirectAfterCopyMove", d.RedirectAfterCopyMove),
|
||||
Sorting: files.Sorting{
|
||||
Asc: a.Fields.GetBoolean("user.sorting.asc", d.Sorting.Asc),
|
||||
By: a.Fields.GetString("user.sorting.by", d.Sorting.By),
|
||||
@@ -251,6 +253,7 @@ var validHookFields = []string{
|
||||
"user.locale",
|
||||
"user.viewMode",
|
||||
"user.singleClick",
|
||||
"user.redirectAfterCopyMove",
|
||||
"user.sorting.by",
|
||||
"user.sorting.asc",
|
||||
"user.commands",
|
||||
|
||||
@@ -240,6 +240,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
||||
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
|
||||
fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode)
|
||||
fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.Defaults.SingleClick)
|
||||
fmt.Fprintf(w, "\tRedirect after Copy/Move:\t%t\n", set.Defaults.RedirectAfterCopyMove)
|
||||
fmt.Fprintf(w, "\tFile Creation Mode:\t%O\n", set.FileMode)
|
||||
fmt.Fprintf(w, "\tDirectory Creation Mode:\t%O\n", set.DirMode)
|
||||
fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " "))
|
||||
|
||||
@@ -393,10 +393,11 @@ func quickSetup(v *viper.Viper, s *storage.Storage) error {
|
||||
MinimumPasswordLength: settings.DefaultMinimumPasswordLength,
|
||||
UserHomeBasePath: settings.DefaultUsersHomeBasePath,
|
||||
Defaults: settings.UserDefaults{
|
||||
Scope: ".",
|
||||
Locale: "en",
|
||||
SingleClick: false,
|
||||
AceEditorTheme: v.GetString("defaults.aceEditorTheme"),
|
||||
Scope: ".",
|
||||
Locale: "en",
|
||||
SingleClick: false,
|
||||
RedirectAfterCopyMove: true,
|
||||
AceEditorTheme: v.GetString("defaults.aceEditorTheme"),
|
||||
Perm: users.Permissions{
|
||||
Admin: false,
|
||||
Execute: true,
|
||||
|
||||
@@ -30,13 +30,14 @@ func printUsers(usrs []*users.User) {
|
||||
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock")
|
||||
|
||||
for _, u := range usrs {
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t\n",
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t\n",
|
||||
u.ID,
|
||||
u.Username,
|
||||
u.Scope,
|
||||
u.Locale,
|
||||
u.ViewMode,
|
||||
u.SingleClick,
|
||||
u.RedirectAfterCopyMove,
|
||||
u.Perm.Admin,
|
||||
u.Perm.Execute,
|
||||
u.Perm.Create,
|
||||
@@ -77,6 +78,7 @@ func addUserFlags(flags *pflag.FlagSet) {
|
||||
flags.String("locale", "en", "locale for users")
|
||||
flags.String("viewMode", string(users.ListViewMode), "view mode for users")
|
||||
flags.Bool("singleClick", false, "use single clicks only")
|
||||
flags.Bool("redirectAfterCopyMove", false, "redirect to destination after copy/move")
|
||||
flags.Bool("dateFormat", false, "use date format (true for absolute time, false for relative)")
|
||||
flags.Bool("hideDotfiles", false, "hide dotfiles")
|
||||
flags.String("aceEditorTheme", "", "ace editor's syntax highlighting theme for users")
|
||||
@@ -110,6 +112,8 @@ func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all
|
||||
defaults.ViewMode, err = getAndParseViewMode(flags)
|
||||
case "singleClick":
|
||||
defaults.SingleClick, err = flags.GetBool(flag.Name)
|
||||
case "redirectAfterCopyMove":
|
||||
defaults.RedirectAfterCopyMove, err = flags.GetBool(flag.Name)
|
||||
case "aceEditorTheme":
|
||||
defaults.AceEditorTheme, err = flags.GetString(flag.Name)
|
||||
case "perm.admin":
|
||||
|
||||
@@ -52,13 +52,14 @@ options you want to change.`,
|
||||
}
|
||||
|
||||
defaults := settings.UserDefaults{
|
||||
Scope: user.Scope,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
Perm: user.Perm,
|
||||
Sorting: user.Sorting,
|
||||
Commands: user.Commands,
|
||||
Scope: user.Scope,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
RedirectAfterCopyMove: user.RedirectAfterCopyMove,
|
||||
Perm: user.Perm,
|
||||
Sorting: user.Sorting,
|
||||
Commands: user.Commands,
|
||||
}
|
||||
|
||||
err = getUserDefaults(flags, &defaults, false)
|
||||
@@ -70,6 +71,7 @@ options you want to change.`,
|
||||
user.Locale = defaults.Locale
|
||||
user.ViewMode = defaults.ViewMode
|
||||
user.SingleClick = defaults.SingleClick
|
||||
user.RedirectAfterCopyMove = defaults.RedirectAfterCopyMove
|
||||
user.Perm = defaults.Perm
|
||||
user.Commands = defaults.Commands
|
||||
user.Sorting = defaults.Sorting
|
||||
|
||||
@@ -71,5 +71,5 @@
|
||||
"vite-plugin-compression2": "^2.3.1",
|
||||
"vue-tsc": "^3.1.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.27.0+sha512.72d699da16b1179c14ba9e64dc71c9a40988cbdc65c264cb0e489db7de917f20dcf4d64d8723625f2969ba52d4b7e2a1170682d9ac2a5dcaeaab732b7e16f04a"
|
||||
"packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48"
|
||||
}
|
||||
|
||||
Generated
+198
-171
@@ -98,7 +98,7 @@ importers:
|
||||
devDependencies:
|
||||
'@intlify/unplugin-vue-i18n':
|
||||
specifier: ^11.0.1
|
||||
version: 11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2)(rollup@4.54.0)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))
|
||||
version: 11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2)(rollup@4.55.1)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))
|
||||
'@tsconfig/node24':
|
||||
specifier: ^24.0.2
|
||||
version: 24.0.3
|
||||
@@ -107,16 +107,16 @@ importers:
|
||||
version: 4.17.12
|
||||
'@types/node':
|
||||
specifier: ^24.10.1
|
||||
version: 24.10.4
|
||||
version: 24.10.6
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^8.37.0
|
||||
version: 8.51.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)
|
||||
version: 8.52.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)
|
||||
'@vitejs/plugin-legacy':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1(terser@5.44.1)(vite@7.3.0(@types/node@24.10.4)(terser@5.44.1)(yaml@2.8.2))
|
||||
version: 7.2.1(terser@5.44.1)(vite@7.3.1(@types/node@24.10.6)(terser@5.44.1)(yaml@2.8.2))
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.3(vite@7.3.0(@types/node@24.10.4)(terser@5.44.1)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))
|
||||
version: 6.0.3(vite@7.3.1(@types/node@24.10.6)(terser@5.44.1)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))
|
||||
'@vue/eslint-config-prettier':
|
||||
specifier: ^10.2.0
|
||||
version: 10.2.0(eslint@9.39.2)(prettier@3.7.4)
|
||||
@@ -155,13 +155,13 @@ importers:
|
||||
version: 5.9.3
|
||||
vite:
|
||||
specifier: ^7.2.2
|
||||
version: 7.3.0(@types/node@24.10.4)(terser@5.44.1)(yaml@2.8.2)
|
||||
version: 7.3.1(@types/node@24.10.6)(terser@5.44.1)(yaml@2.8.2)
|
||||
vite-plugin-compression2:
|
||||
specifier: ^2.3.1
|
||||
version: 2.4.0(rollup@4.54.0)
|
||||
version: 2.4.0(rollup@4.55.1)
|
||||
vue-tsc:
|
||||
specifier: ^3.1.3
|
||||
version: 3.2.1(typescript@5.9.3)
|
||||
version: 3.2.2(typescript@5.9.3)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -1143,113 +1143,128 @@ packages:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.54.0':
|
||||
resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==}
|
||||
'@rollup/rollup-android-arm-eabi@4.55.1':
|
||||
resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-android-arm64@4.54.0':
|
||||
resolution: {integrity: sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==}
|
||||
'@rollup/rollup-android-arm64@4.55.1':
|
||||
resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.54.0':
|
||||
resolution: {integrity: sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==}
|
||||
'@rollup/rollup-darwin-arm64@4.55.1':
|
||||
resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.54.0':
|
||||
resolution: {integrity: sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==}
|
||||
'@rollup/rollup-darwin-x64@4.55.1':
|
||||
resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.54.0':
|
||||
resolution: {integrity: sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==}
|
||||
'@rollup/rollup-freebsd-arm64@4.55.1':
|
||||
resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.54.0':
|
||||
resolution: {integrity: sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==}
|
||||
'@rollup/rollup-freebsd-x64@4.55.1':
|
||||
resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.54.0':
|
||||
resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==}
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.55.1':
|
||||
resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.54.0':
|
||||
resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==}
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.55.1':
|
||||
resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.54.0':
|
||||
resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==}
|
||||
'@rollup/rollup-linux-arm64-gnu@4.55.1':
|
||||
resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.54.0':
|
||||
resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==}
|
||||
'@rollup/rollup-linux-arm64-musl@4.55.1':
|
||||
resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.54.0':
|
||||
resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==}
|
||||
'@rollup/rollup-linux-loong64-gnu@4.55.1':
|
||||
resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.54.0':
|
||||
resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==}
|
||||
'@rollup/rollup-linux-loong64-musl@4.55.1':
|
||||
resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.55.1':
|
||||
resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.54.0':
|
||||
resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==}
|
||||
'@rollup/rollup-linux-ppc64-musl@4.55.1':
|
||||
resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.55.1':
|
||||
resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.54.0':
|
||||
resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==}
|
||||
'@rollup/rollup-linux-riscv64-musl@4.55.1':
|
||||
resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.54.0':
|
||||
resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==}
|
||||
'@rollup/rollup-linux-s390x-gnu@4.55.1':
|
||||
resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.54.0':
|
||||
resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==}
|
||||
'@rollup/rollup-linux-x64-gnu@4.55.1':
|
||||
resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.54.0':
|
||||
resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==}
|
||||
'@rollup/rollup-linux-x64-musl@4.55.1':
|
||||
resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.54.0':
|
||||
resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==}
|
||||
'@rollup/rollup-openbsd-x64@4.55.1':
|
||||
resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.55.1':
|
||||
resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.54.0':
|
||||
resolution: {integrity: sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==}
|
||||
'@rollup/rollup-win32-arm64-msvc@4.55.1':
|
||||
resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.54.0':
|
||||
resolution: {integrity: sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==}
|
||||
'@rollup/rollup-win32-ia32-msvc@4.55.1':
|
||||
resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.54.0':
|
||||
resolution: {integrity: sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==}
|
||||
'@rollup/rollup-win32-x64-gnu@4.55.1':
|
||||
resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.54.0':
|
||||
resolution: {integrity: sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==}
|
||||
'@rollup/rollup-win32-x64-msvc@4.55.1':
|
||||
resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
@@ -1272,8 +1287,8 @@ packages:
|
||||
'@types/lodash@4.17.13':
|
||||
resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==}
|
||||
|
||||
'@types/node@24.10.4':
|
||||
resolution: {integrity: sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==}
|
||||
'@types/node@24.10.6':
|
||||
resolution: {integrity: sha512-B8h60xgJMR/xmgyX9fncRzEW9gCxoJjdenUhke2v1JGOd/V66KopmWrLPXi5oUI4VuiGK+d+HlXJjDRZMj21EQ==}
|
||||
|
||||
'@types/trusted-types@2.0.7':
|
||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||
@@ -1289,11 +1304,11 @@ packages:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.51.0':
|
||||
resolution: {integrity: sha512-XtssGWJvypyM2ytBnSnKtHYOGT+4ZwTnBVl36TA4nRO2f4PRNGz5/1OszHzcZCvcBMh+qb7I06uoCmLTRdR9og==}
|
||||
'@typescript-eslint/eslint-plugin@8.52.0':
|
||||
resolution: {integrity: sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^8.51.0
|
||||
'@typescript-eslint/parser': ^8.52.0
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
@@ -1316,8 +1331,8 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/project-service@8.51.0':
|
||||
resolution: {integrity: sha512-Luv/GafO07Z7HpiI7qeEW5NW8HUtZI/fo/kE0YbtQEFpJRUuR0ajcWfCE5bnMvL7QQFrmT/odMe8QZww8X2nfQ==}
|
||||
'@typescript-eslint/project-service@8.52.0':
|
||||
resolution: {integrity: sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
@@ -1330,8 +1345,8 @@ packages:
|
||||
resolution: {integrity: sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/scope-manager@8.51.0':
|
||||
resolution: {integrity: sha512-JhhJDVwsSx4hiOEQPeajGhCWgBMBwVkxC/Pet53EpBVs7zHHtayKefw1jtPaNRXpI9RA2uocdmpdfE7T+NrizA==}
|
||||
'@typescript-eslint/scope-manager@8.52.0':
|
||||
resolution: {integrity: sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.37.0':
|
||||
@@ -1346,8 +1361,8 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.51.0':
|
||||
resolution: {integrity: sha512-Qi5bSy/vuHeWyir2C8u/uqGMIlIDu8fuiYWv48ZGlZ/k+PRPHtaAu7erpc7p5bzw2WNNSniuxoMSO4Ar6V9OXw==}
|
||||
'@typescript-eslint/tsconfig-utils@8.52.0':
|
||||
resolution: {integrity: sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
@@ -1359,8 +1374,8 @@ packages:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/type-utils@8.51.0':
|
||||
resolution: {integrity: sha512-0XVtYzxnobc9K0VU7wRWg1yiUrw4oQzexCG2V2IDxxCxhqBMSMbjB+6o91A+Uc0GWtgjCa3Y8bi7hwI0Tu4n5Q==}
|
||||
'@typescript-eslint/type-utils@8.52.0':
|
||||
resolution: {integrity: sha512-JD3wKBRWglYRQkAtsyGz1AewDu3mTc7NtRjR/ceTyGoPqmdS5oCdx/oZMWD5Zuqmo6/MpsYs0wp6axNt88/2EQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@@ -1374,8 +1389,8 @@ packages:
|
||||
resolution: {integrity: sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/types@8.51.0':
|
||||
resolution: {integrity: sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag==}
|
||||
'@typescript-eslint/types@8.52.0':
|
||||
resolution: {integrity: sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.37.0':
|
||||
@@ -1390,8 +1405,8 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.51.0':
|
||||
resolution: {integrity: sha512-1qNjGqFRmlq0VW5iVlcyHBbCjPB7y6SxpBkrbhNWMy/65ZoncXCEPJxkRZL8McrseNH6lFhaxCIaX+vBuFnRng==}
|
||||
'@typescript-eslint/typescript-estree@8.52.0':
|
||||
resolution: {integrity: sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <6.0.0'
|
||||
@@ -1403,8 +1418,8 @@ packages:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.9.0'
|
||||
|
||||
'@typescript-eslint/utils@8.51.0':
|
||||
resolution: {integrity: sha512-11rZYxSe0zabiKaCP2QAwRf/dnmgFgvTmeDTtZvUvXG3UuAdg/GU02NExmmIXzz3vLGgMdtrIosI84jITQOxUA==}
|
||||
'@typescript-eslint/utils@8.52.0':
|
||||
resolution: {integrity: sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
@@ -1418,8 +1433,8 @@ packages:
|
||||
resolution: {integrity: sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.51.0':
|
||||
resolution: {integrity: sha512-mM/JRQOzhVN1ykejrvwnBRV3+7yTKK8tVANVN3o1O0t0v7o+jqdVu9crPy5Y9dov15TJk/FTIgoUGHrTOVL3Zg==}
|
||||
'@typescript-eslint/visitor-keys@8.52.0':
|
||||
resolution: {integrity: sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@videojs/http-streaming@3.17.2':
|
||||
@@ -1499,8 +1514,8 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@vue/language-core@3.2.1':
|
||||
resolution: {integrity: sha512-g6oSenpnGMtpxHGAwKuu7HJJkNZpemK/zg3vZzZbJ6cnnXq1ssxuNrXSsAHYM3NvH8p4IkTw+NLmuxyeYz4r8A==}
|
||||
'@vue/language-core@3.2.2':
|
||||
resolution: {integrity: sha512-5DAuhxsxBN9kbriklh3Q5AMaJhyOCNiQJvCskN9/30XOpdLiqZU9Q+WvjArP17ubdGEyZtBzlIeG5nIjEbNOrQ==}
|
||||
|
||||
'@vue/reactivity@3.5.26':
|
||||
resolution: {integrity: sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==}
|
||||
@@ -2421,8 +2436,8 @@ packages:
|
||||
rfdc@1.4.1:
|
||||
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
|
||||
|
||||
rollup@4.54.0:
|
||||
resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==}
|
||||
rollup@4.55.1:
|
||||
resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
@@ -2618,8 +2633,8 @@ packages:
|
||||
vite-plugin-compression2@2.4.0:
|
||||
resolution: {integrity: sha512-8J4CBF1+dM1I06azba/eXJuJHinLF0Am7lUvRH8AZpu0otJoBaDEnxrIEr5iPZJSwH0AEglJGYCveh7pN52jCg==}
|
||||
|
||||
vite@7.3.0:
|
||||
resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==}
|
||||
vite@7.3.1:
|
||||
resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -2697,8 +2712,8 @@ packages:
|
||||
peerDependencies:
|
||||
vue: ^3.0.2
|
||||
|
||||
vue-tsc@3.2.1:
|
||||
resolution: {integrity: sha512-I23Rk8dkQfmcSbxDO0dmg9ioMLjKA1pjlU3Lz6Jfk2pMGu3Uryu9810XkcZH24IzPbhzPCnkKo2rEMRX0skSrw==}
|
||||
vue-tsc@3.2.2:
|
||||
resolution: {integrity: sha512-r9YSia/VgGwmbbfC06hDdAatH634XJ9nVl6Zrnz1iK4ucp8Wu78kawplXnIDa3MSu1XdQQePTHLXYwPDWn+nyQ==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
typescript: '>=5.0.0'
|
||||
@@ -3649,13 +3664,13 @@ snapshots:
|
||||
|
||||
'@intlify/shared@11.2.8': {}
|
||||
|
||||
'@intlify/unplugin-vue-i18n@11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2)(rollup@4.54.0)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))':
|
||||
'@intlify/unplugin-vue-i18n@11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2)(rollup@4.55.1)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2)
|
||||
'@intlify/bundle-utils': 11.0.3(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))
|
||||
'@intlify/shared': 11.2.2
|
||||
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.2.2)(@vue/compiler-dom@3.5.26)(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.54.0)
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.55.1)
|
||||
'@typescript-eslint/scope-manager': 8.49.0
|
||||
'@typescript-eslint/typescript-estree': 8.49.0(typescript@5.9.3)
|
||||
debug: 4.4.3
|
||||
@@ -3722,78 +3737,87 @@ snapshots:
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-beta.53': {}
|
||||
|
||||
'@rollup/pluginutils@5.3.0(rollup@4.54.0)':
|
||||
'@rollup/pluginutils@5.3.0(rollup@4.55.1)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
estree-walker: 2.0.2
|
||||
picomatch: 4.0.3
|
||||
optionalDependencies:
|
||||
rollup: 4.54.0
|
||||
rollup: 4.55.1
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.54.0':
|
||||
'@rollup/rollup-android-arm-eabi@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm64@4.54.0':
|
||||
'@rollup/rollup-android-arm64@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.54.0':
|
||||
'@rollup/rollup-darwin-arm64@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.54.0':
|
||||
'@rollup/rollup-darwin-x64@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.54.0':
|
||||
'@rollup/rollup-freebsd-arm64@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.54.0':
|
||||
'@rollup/rollup-freebsd-x64@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.54.0':
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.54.0':
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.54.0':
|
||||
'@rollup/rollup-linux-arm64-gnu@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.54.0':
|
||||
'@rollup/rollup-linux-arm64-musl@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.54.0':
|
||||
'@rollup/rollup-linux-loong64-gnu@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.54.0':
|
||||
'@rollup/rollup-linux-loong64-musl@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.54.0':
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.54.0':
|
||||
'@rollup/rollup-linux-ppc64-musl@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.54.0':
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.54.0':
|
||||
'@rollup/rollup-linux-riscv64-musl@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.54.0':
|
||||
'@rollup/rollup-linux-s390x-gnu@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.54.0':
|
||||
'@rollup/rollup-linux-x64-gnu@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.54.0':
|
||||
'@rollup/rollup-linux-x64-musl@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.54.0':
|
||||
'@rollup/rollup-openbsd-x64@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.54.0':
|
||||
'@rollup/rollup-openharmony-arm64@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.54.0':
|
||||
'@rollup/rollup-win32-arm64-msvc@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@tsconfig/node24@24.0.3': {}
|
||||
@@ -3812,7 +3836,7 @@ snapshots:
|
||||
|
||||
'@types/lodash@4.17.13': {}
|
||||
|
||||
'@types/node@24.10.4':
|
||||
'@types/node@24.10.6':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
@@ -3838,14 +3862,14 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.51.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)':
|
||||
'@typescript-eslint/eslint-plugin@8.52.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
'@typescript-eslint/parser': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
|
||||
'@typescript-eslint/scope-manager': 8.51.0
|
||||
'@typescript-eslint/type-utils': 8.51.0(eslint@9.39.2)(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.51.0(eslint@9.39.2)(typescript@5.9.3)
|
||||
'@typescript-eslint/visitor-keys': 8.51.0
|
||||
'@typescript-eslint/scope-manager': 8.52.0
|
||||
'@typescript-eslint/type-utils': 8.52.0(eslint@9.39.2)(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.52.0(eslint@9.39.2)(typescript@5.9.3)
|
||||
'@typescript-eslint/visitor-keys': 8.52.0
|
||||
eslint: 9.39.2
|
||||
ignore: 7.0.5
|
||||
natural-compare: 1.4.0
|
||||
@@ -3884,10 +3908,10 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/project-service@8.51.0(typescript@5.9.3)':
|
||||
'@typescript-eslint/project-service@8.52.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/tsconfig-utils': 8.51.0(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.51.0
|
||||
'@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.52.0
|
||||
debug: 4.4.3
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
@@ -3903,10 +3927,10 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.49.0
|
||||
'@typescript-eslint/visitor-keys': 8.49.0
|
||||
|
||||
'@typescript-eslint/scope-manager@8.51.0':
|
||||
'@typescript-eslint/scope-manager@8.52.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.51.0
|
||||
'@typescript-eslint/visitor-keys': 8.51.0
|
||||
'@typescript-eslint/types': 8.52.0
|
||||
'@typescript-eslint/visitor-keys': 8.52.0
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.37.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
@@ -3916,7 +3940,7 @@ snapshots:
|
||||
dependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
'@typescript-eslint/tsconfig-utils@8.51.0(typescript@5.9.3)':
|
||||
'@typescript-eslint/tsconfig-utils@8.52.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
@@ -3932,11 +3956,11 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/type-utils@8.51.0(eslint@9.39.2)(typescript@5.9.3)':
|
||||
'@typescript-eslint/type-utils@8.52.0(eslint@9.39.2)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.51.0
|
||||
'@typescript-eslint/typescript-estree': 8.51.0(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.51.0(eslint@9.39.2)(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.52.0
|
||||
'@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.52.0(eslint@9.39.2)(typescript@5.9.3)
|
||||
debug: 4.4.3
|
||||
eslint: 9.39.2
|
||||
ts-api-utils: 2.4.0(typescript@5.9.3)
|
||||
@@ -3948,7 +3972,7 @@ snapshots:
|
||||
|
||||
'@typescript-eslint/types@8.49.0': {}
|
||||
|
||||
'@typescript-eslint/types@8.51.0': {}
|
||||
'@typescript-eslint/types@8.52.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.37.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
@@ -3981,12 +4005,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.51.0(typescript@5.9.3)':
|
||||
'@typescript-eslint/typescript-estree@8.52.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/project-service': 8.51.0(typescript@5.9.3)
|
||||
'@typescript-eslint/tsconfig-utils': 8.51.0(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.51.0
|
||||
'@typescript-eslint/visitor-keys': 8.51.0
|
||||
'@typescript-eslint/project-service': 8.52.0(typescript@5.9.3)
|
||||
'@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3)
|
||||
'@typescript-eslint/types': 8.52.0
|
||||
'@typescript-eslint/visitor-keys': 8.52.0
|
||||
debug: 4.4.3
|
||||
minimatch: 9.0.5
|
||||
semver: 7.7.3
|
||||
@@ -4007,12 +4031,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.51.0(eslint@9.39.2)(typescript@5.9.3)':
|
||||
'@typescript-eslint/utils@8.52.0(eslint@9.39.2)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2)
|
||||
'@typescript-eslint/scope-manager': 8.51.0
|
||||
'@typescript-eslint/types': 8.51.0
|
||||
'@typescript-eslint/typescript-estree': 8.51.0(typescript@5.9.3)
|
||||
'@typescript-eslint/scope-manager': 8.52.0
|
||||
'@typescript-eslint/types': 8.52.0
|
||||
'@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3)
|
||||
eslint: 9.39.2
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
@@ -4028,9 +4052,9 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.49.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.51.0':
|
||||
'@typescript-eslint/visitor-keys@8.52.0':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.51.0
|
||||
'@typescript-eslint/types': 8.52.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@videojs/http-streaming@3.17.2(video.js@8.23.4)':
|
||||
@@ -4055,7 +4079,7 @@ snapshots:
|
||||
global: 4.4.0
|
||||
is-function: 1.0.2
|
||||
|
||||
'@vitejs/plugin-legacy@7.2.1(terser@5.44.1)(vite@7.3.0(@types/node@24.10.4)(terser@5.44.1)(yaml@2.8.2))':
|
||||
'@vitejs/plugin-legacy@7.2.1(terser@5.44.1)(vite@7.3.1(@types/node@24.10.6)(terser@5.44.1)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5)
|
||||
@@ -4070,14 +4094,14 @@ snapshots:
|
||||
regenerator-runtime: 0.14.1
|
||||
systemjs: 6.15.1
|
||||
terser: 5.44.1
|
||||
vite: 7.3.0(@types/node@24.10.4)(terser@5.44.1)(yaml@2.8.2)
|
||||
vite: 7.3.1(@types/node@24.10.6)(terser@5.44.1)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitejs/plugin-vue@6.0.3(vite@7.3.0(@types/node@24.10.4)(terser@5.44.1)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))':
|
||||
'@vitejs/plugin-vue@6.0.3(vite@7.3.1(@types/node@24.10.6)(terser@5.44.1)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.53
|
||||
vite: 7.3.0(@types/node@24.10.4)(terser@5.44.1)(yaml@2.8.2)
|
||||
vite: 7.3.1(@types/node@24.10.6)(terser@5.44.1)(yaml@2.8.2)
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
|
||||
'@volar/language-core@2.4.27':
|
||||
@@ -4164,7 +4188,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vue/language-core@3.2.1':
|
||||
'@vue/language-core@3.2.2':
|
||||
dependencies:
|
||||
'@volar/language-core': 2.4.27
|
||||
'@vue/compiler-dom': 3.5.26
|
||||
@@ -5068,32 +5092,35 @@ snapshots:
|
||||
|
||||
rfdc@1.4.1: {}
|
||||
|
||||
rollup@4.54.0:
|
||||
rollup@4.55.1:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
optionalDependencies:
|
||||
'@rollup/rollup-android-arm-eabi': 4.54.0
|
||||
'@rollup/rollup-android-arm64': 4.54.0
|
||||
'@rollup/rollup-darwin-arm64': 4.54.0
|
||||
'@rollup/rollup-darwin-x64': 4.54.0
|
||||
'@rollup/rollup-freebsd-arm64': 4.54.0
|
||||
'@rollup/rollup-freebsd-x64': 4.54.0
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.54.0
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.54.0
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.54.0
|
||||
'@rollup/rollup-linux-arm64-musl': 4.54.0
|
||||
'@rollup/rollup-linux-loong64-gnu': 4.54.0
|
||||
'@rollup/rollup-linux-ppc64-gnu': 4.54.0
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.54.0
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.54.0
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.54.0
|
||||
'@rollup/rollup-linux-x64-gnu': 4.54.0
|
||||
'@rollup/rollup-linux-x64-musl': 4.54.0
|
||||
'@rollup/rollup-openharmony-arm64': 4.54.0
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.54.0
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.54.0
|
||||
'@rollup/rollup-win32-x64-gnu': 4.54.0
|
||||
'@rollup/rollup-win32-x64-msvc': 4.54.0
|
||||
'@rollup/rollup-android-arm-eabi': 4.55.1
|
||||
'@rollup/rollup-android-arm64': 4.55.1
|
||||
'@rollup/rollup-darwin-arm64': 4.55.1
|
||||
'@rollup/rollup-darwin-x64': 4.55.1
|
||||
'@rollup/rollup-freebsd-arm64': 4.55.1
|
||||
'@rollup/rollup-freebsd-x64': 4.55.1
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.55.1
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.55.1
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.55.1
|
||||
'@rollup/rollup-linux-arm64-musl': 4.55.1
|
||||
'@rollup/rollup-linux-loong64-gnu': 4.55.1
|
||||
'@rollup/rollup-linux-loong64-musl': 4.55.1
|
||||
'@rollup/rollup-linux-ppc64-gnu': 4.55.1
|
||||
'@rollup/rollup-linux-ppc64-musl': 4.55.1
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.55.1
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.55.1
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.55.1
|
||||
'@rollup/rollup-linux-x64-gnu': 4.55.1
|
||||
'@rollup/rollup-linux-x64-musl': 4.55.1
|
||||
'@rollup/rollup-openbsd-x64': 4.55.1
|
||||
'@rollup/rollup-openharmony-arm64': 4.55.1
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.55.1
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.55.1
|
||||
'@rollup/rollup-win32-x64-gnu': 4.55.1
|
||||
'@rollup/rollup-win32-x64-msvc': 4.55.1
|
||||
fsevents: 2.3.3
|
||||
|
||||
run-parallel@1.2.0:
|
||||
@@ -5282,23 +5309,23 @@ snapshots:
|
||||
dependencies:
|
||||
global: 4.4.0
|
||||
|
||||
vite-plugin-compression2@2.4.0(rollup@4.54.0):
|
||||
vite-plugin-compression2@2.4.0(rollup@4.55.1):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.54.0)
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.55.1)
|
||||
tar-mini: 0.2.0
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
|
||||
vite@7.3.0(@types/node@24.10.4)(terser@5.44.1)(yaml@2.8.2):
|
||||
vite@7.3.1(@types/node@24.10.6)(terser@5.44.1)(yaml@2.8.2):
|
||||
dependencies:
|
||||
esbuild: 0.27.2
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
picomatch: 4.0.3
|
||||
postcss: 8.5.6
|
||||
rollup: 4.54.0
|
||||
rollup: 4.55.1
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
'@types/node': 24.10.4
|
||||
'@types/node': 24.10.6
|
||||
fsevents: 2.3.3
|
||||
terser: 5.44.1
|
||||
yaml: 2.8.2
|
||||
@@ -5346,10 +5373,10 @@ snapshots:
|
||||
dependencies:
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
|
||||
vue-tsc@3.2.1(typescript@5.9.3):
|
||||
vue-tsc@3.2.2(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@volar/typescript': 2.4.27
|
||||
'@vue/language-core': 3.2.1
|
||||
'@vue/language-core': 3.2.2
|
||||
typescript: 5.9.3
|
||||
|
||||
vue@3.5.26(typescript@5.9.3):
|
||||
|
||||
@@ -109,7 +109,8 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$router.push({ path: this.dest });
|
||||
if (this.user.redirectAfterCopyMove)
|
||||
this.$router.push({ path: this.dest });
|
||||
})
|
||||
.catch((e) => {
|
||||
buttons.done("copy");
|
||||
|
||||
@@ -79,7 +79,7 @@ export default {
|
||||
computed: {
|
||||
...mapState(useFileStore, ["req", "selected"]),
|
||||
...mapState(useAuthStore, ["user"]),
|
||||
...mapWritableState(useFileStore, ["preselect"]),
|
||||
...mapWritableState(useFileStore, ["reload", "preselect"]),
|
||||
excludedFolders() {
|
||||
return this.selected
|
||||
.filter((idx) => this.req.items[idx].isDir)
|
||||
@@ -108,7 +108,9 @@ export default {
|
||||
.then(() => {
|
||||
buttons.success("move");
|
||||
this.preselect = removePrefix(items[0].to);
|
||||
this.$router.push({ path: this.dest });
|
||||
if (this.user.redirectAfterCopyMove)
|
||||
this.$router.push({ path: this.dest });
|
||||
else this.reload = true;
|
||||
})
|
||||
.catch((e) => {
|
||||
buttons.done("move");
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"ok": "موافق",
|
||||
"permalink": "الحصول على رابط دائم",
|
||||
"previous": "السابق",
|
||||
"preview": "Preview",
|
||||
"preview": "معاينة",
|
||||
"publish": "نشر",
|
||||
"rename": "إعادة تسمية",
|
||||
"replace": "استبدال",
|
||||
@@ -43,11 +43,11 @@
|
||||
"upload": "رفع",
|
||||
"openFile": "فتح الملف",
|
||||
"discardChanges": "إلغاء التغييرات",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"stopSearch": "توقف عن البحث",
|
||||
"saveChanges": "حفظ التغييرات",
|
||||
"editAsText": "تعديل على شكل نص",
|
||||
"increaseFontSize": "زيادة حجم الخط",
|
||||
"decreaseFontSize": "تصغير حجم الخط"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "تحميل الملف",
|
||||
@@ -80,7 +80,7 @@
|
||||
"sortByName": "الترتيب باﻹسم",
|
||||
"sortBySize": "الترتيب بالحجم",
|
||||
"noPreview": "لا يوجد عرض مسبق لهذا الملف.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvTooLarge": "حجم الملف اكبر من (<5MB), يرجى تحميل الملف للمعاينة",
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
@@ -138,7 +138,7 @@
|
||||
"filesSelected": "تم تحديد {count} ملفات.",
|
||||
"lastModified": "آخر تعديل",
|
||||
"move": "نقل",
|
||||
"moveMessage": "إختر مكان جديد للملفات أو المجلدات المراد نقلها:",
|
||||
"moveMessage": "اختر منزلاً جديداً لملفك (ملفاتك)/مجلدك (مجلداتك):",
|
||||
"newArchetype": "إنشاء منشور من المنشور اﻷصلي. الملف سيتم انشاءه في مجلد المحتويات.",
|
||||
"newDir": "مجلد جديد",
|
||||
"newDirMessage": "أدخل اسم المجلد الجديد.",
|
||||
@@ -189,15 +189,15 @@
|
||||
"commandRunner": "منفذ اﻷوامر",
|
||||
"commandRunnerHelp": "هنا بإمكانك تعيين اﻷوامر التي سيتم تنفيذها في اﻷحداث المسماة. يجب كتابة أمر واحد في كل سطر. ستكون المتغيرات البيئية (env) {0} و {1} متاحة، حيث {0} نسبي لـ {1}. لمزيد من المعلومات حول هذه الميزة و المتغيرات البيئية المتاحة، يرجى قراءة {2}.",
|
||||
"commandsUpdated": "تم تحديث اﻷوامر",
|
||||
"createUserDir": "إنشاء مجلد المستخدم (home) تلقائياً عند إنشاء مستخدم جديد",
|
||||
"createUserDir": "إنشاء مجلد المستخدم الرئيسي تلقائياً عند إنشاء مستخدم جديد",
|
||||
"minimumPasswordLength": "Minimum password length",
|
||||
"tusUploads": "التحميلات المتقطعة",
|
||||
"tusUploadsHelp": "يدعم متصفح الملفات تحميل الملفات المتقطعة، مما يسمح بتحميلات الملفات بشكل فعال و موثوق و قابلة للمتابغة و متقطعة حتى على الشبكات غير الموثوقة.",
|
||||
"tusUploadsChunkSize": "يشير إلى الحد اﻷقصى لحجم الطلب (سيتم استخدام التحميل المباشر للتحميلات صغيرة الخحم). يمكنك إدخال عدد صحيح عادي يدل على الحجم بوحدة البايت أو نمظ مثل10MB, 1GB, إلخ.",
|
||||
"tusUploadsRetryCount": "عدد مرات إعادة المحاولة إذا فشلت عملية تحميل القطعة.",
|
||||
"userHomeBasePath": "المسار الرئيسي لمجلد المستخدم (home)",
|
||||
"userHomeBasePath": "المسار الرئيسي لمجلد المستخدم الرئيسي",
|
||||
"userScopeGenerationPlaceholder": "سيتم تعيين نطاق المستخدم تلقائياً",
|
||||
"createUserHomeDirectory": "إنشاء مجلد المستخدم (home)",
|
||||
"createUserHomeDirectory": "إنشاء مجلد المستخدم الرئيسي",
|
||||
"customStylesheet": "ستايل مخصص",
|
||||
"defaultUserDescription": "هذه اﻹعدادات اﻹفتراضية للمستخدمين الجدد.",
|
||||
"disableExternalLinks": "تعطيل الروابط الخارجية (بإسثناء الوثائق)",
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "إدارة المستخدمين",
|
||||
"userUpdated": "تم تعديل المستخدم",
|
||||
"username": "إسم المستخدم",
|
||||
"users": "المستخدمين"
|
||||
"users": "المستخدمين",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "مساعدة",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Управление на потребители",
|
||||
"userUpdated": "Потребителя е обновен!",
|
||||
"username": "Потребителско име",
|
||||
"users": "Потребители"
|
||||
"users": "Потребители",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Помощ",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Administració d'usuaris",
|
||||
"userUpdated": "Usuari actualitzat!",
|
||||
"username": "Usuari",
|
||||
"users": "Usuaris"
|
||||
"users": "Usuaris",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ajuda",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Správa uživatelů",
|
||||
"userUpdated": "Uživatel aktualizován!",
|
||||
"username": "Uživatelské jméno",
|
||||
"users": "Uživatelé"
|
||||
"users": "Uživatelé",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Nápověda",
|
||||
|
||||
@@ -43,11 +43,11 @@
|
||||
"upload": "Upload",
|
||||
"openFile": "Datei öffnen",
|
||||
"discardChanges": "Verwerfen",
|
||||
"stopSearch": "Stop searching",
|
||||
"stopSearch": "Suche abbrechen",
|
||||
"saveChanges": "Änderungen speichern",
|
||||
"editAsText": "Als Text bearbeiten",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"increaseFontSize": "Schriftgröße vergrößern",
|
||||
"decreaseFontSize": "Schriftgröße verkleinern"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download Datei",
|
||||
@@ -82,12 +82,12 @@
|
||||
"noPreview": "Für diese Datei ist keine Vorschau verfügbar.",
|
||||
"csvTooLarge": "Die CSV-Datei ist zu groß für die Vorschau (>5 MB). Bitte herunterladen, um sie anzuzeigen.",
|
||||
"csvLoadFailed": "Fehler beim Laden der CSV-Datei.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"showingRows": "{count} Zeile(n) werden angezeigt",
|
||||
"columnSeparator": "Spaltentrennzeichen",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
"comma": "Komma (,)",
|
||||
"semicolon": "Semikolon (;)",
|
||||
"both": "Sowohl (,) als auch (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
@@ -214,7 +214,7 @@
|
||||
"instanceName": "Instanzname",
|
||||
"language": "Sprache",
|
||||
"lockPassword": "Verhindere, dass der Benutzer sein Passwort ändert",
|
||||
"newPassword": "Ihr neues Passwort.",
|
||||
"newPassword": "Ihr neues Passwort",
|
||||
"newPasswordConfirm": "Bestätigen Sie Ihr neues Passwort",
|
||||
"newUser": "Neuer Benutzer",
|
||||
"password": "Passwort",
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Benutzerverwaltung",
|
||||
"userUpdated": "Benutzer aktualisiert!",
|
||||
"username": "Nutzername",
|
||||
"users": "Nutzer"
|
||||
"users": "Nutzer",
|
||||
"currentPassword": "Ihr aktuelles Passwort"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hilfe",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Διαχείριση χρηστών",
|
||||
"userUpdated": "Ο χρήστης ενημερώθηκε!",
|
||||
"username": "Όνομα χρήστη",
|
||||
"users": "Χρήστες"
|
||||
"users": "Χρήστες",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Βοήθεια",
|
||||
|
||||
@@ -232,6 +232,7 @@
|
||||
"permissions": "Permissions",
|
||||
"permissionsHelp": "You can set the user to be an administrator or choose the permissions individually. If you select \"Administrator\", all of the other options will be automatically checked. The management of users remains a privilege of an administrator.\n",
|
||||
"profileSettings": "Profile Settings",
|
||||
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||
"ruleExample1": "prevents the access to any dotfile (such as .git, .gitignore) in every folder.\n",
|
||||
"ruleExample2": "blocks the access to the file named Caddyfile on the root of the scope.",
|
||||
"rules": "Rules",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Administración de usuarios",
|
||||
"userUpdated": "¡Usuario actualizado!",
|
||||
"username": "Usuario",
|
||||
"users": "Usuarios"
|
||||
"users": "Usuarios",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ayuda",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "مدیریت کاربران",
|
||||
"userUpdated": "کاربر به روز شد!",
|
||||
"username": "نام کاربری",
|
||||
"users": "کاربران"
|
||||
"users": "کاربران",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "راهنما",
|
||||
|
||||
@@ -43,11 +43,11 @@
|
||||
"upload": "Importer",
|
||||
"openFile": "Ouvrir le fichier",
|
||||
"discardChanges": "Annuler",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
"stopSearch": "Arrêter recherche",
|
||||
"saveChanges": "Enregistrer changements",
|
||||
"editAsText": "Editer comme Texte",
|
||||
"increaseFontSize": "Augmenter taille police",
|
||||
"decreaseFontSize": "Réduire taille police"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Télécharger le fichier",
|
||||
@@ -80,14 +80,14 @@
|
||||
"sortByName": "Trier par nom",
|
||||
"sortBySize": "Trier par taille",
|
||||
"noPreview": "L'aperçu n'est pas disponible pour ce fichier.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvTooLarge": "Le fichier CSV est trop volumineux pour être prévisualisé (>5MB). Veuillez le télécharger pour le voir.",
|
||||
"csvLoadFailed": "Impossible de charger le fichier CSV.",
|
||||
"showingRows": "Affichage de {count} ligne(s)",
|
||||
"columnSeparator": "Séparateur de Colonnes",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
"comma": "Virgule (,)",
|
||||
"semicolon": "Point-virgule (;)",
|
||||
"both": "Les (,) et (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
@@ -115,9 +115,9 @@
|
||||
"username": "Utilisateur·ice",
|
||||
"usernameTaken": "Le nom d'utilisateur·ice est déjà pris",
|
||||
"wrongCredentials": "Identifiants incorrects !",
|
||||
"passwordTooShort": "Password must be at least {min} characters",
|
||||
"passwordTooShort": "Le mot de passe doit contenir au moins {min} caractères",
|
||||
"logout_reasons": {
|
||||
"inactivity": "You have been logged out due to inactivity."
|
||||
"inactivity": "Vous avez été déconnecté(e) en raison d'une inactivité prolongée."
|
||||
}
|
||||
},
|
||||
"permanent": "Permanent",
|
||||
@@ -172,7 +172,7 @@
|
||||
"video": "Vidéo"
|
||||
},
|
||||
"settings": {
|
||||
"aceEditorTheme": "Ace editor theme",
|
||||
"aceEditorTheme": "Éditeur de Thème Ace",
|
||||
"admin": "Admin",
|
||||
"administrator": "Administrateur·ice",
|
||||
"allowCommands": "Exécuter des commandes",
|
||||
@@ -180,7 +180,7 @@
|
||||
"allowNew": "Créer de nouveaux fichiers et dossiers",
|
||||
"allowPublish": "Publier de nouveaux posts et pages",
|
||||
"allowSignup": "Autoriser les utilisateur·ices à s'inscrire",
|
||||
"hideLoginButton": "Hide the login button from public pages",
|
||||
"hideLoginButton": "Cacher le bouton d’identification sur les pages publiques",
|
||||
"avoidChanges": "(Laisser vide pour conserver l'actuel)",
|
||||
"branding": "Image de marque",
|
||||
"brandingDirectoryPath": "Chemin du dossier d'image de marque",
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Gestion des utilisateur·ices",
|
||||
"userUpdated": "Utilisateur·ice mis à jour !",
|
||||
"username": "Nom d'utilisateur·ice",
|
||||
"users": "Utilisateur·ices"
|
||||
"users": "Utilisateur·ices",
|
||||
"currentPassword": "Mot de Passe Actuel"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Aide",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "ניהול משתמש",
|
||||
"userUpdated": "המשתמש עודכן!",
|
||||
"username": "שם משתמש",
|
||||
"users": "משתמשים"
|
||||
"users": "משתמשים",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "עזרה",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Upravljanje Korisnicima",
|
||||
"userUpdated": "Korisnik ažuriran!",
|
||||
"username": "Korisničko ime",
|
||||
"users": "Korisnici"
|
||||
"users": "Korisnici",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Pomoć",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Felhasználókezelés",
|
||||
"userUpdated": "Felhasználó frissítve!",
|
||||
"username": "Felhasználói név",
|
||||
"users": "Felhasználók"
|
||||
"users": "Felhasználók",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Súgó",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Notendastýring",
|
||||
"userUpdated": "Notandastillingar vistaðar!",
|
||||
"username": "Notendanafn",
|
||||
"users": "Notendur"
|
||||
"users": "Notendur",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hjálp",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Gestione degli utenti",
|
||||
"userUpdated": "Utente aggiornato!",
|
||||
"username": "Nome utente",
|
||||
"users": "Utenti"
|
||||
"users": "Utenti",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Aiuto",
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
"update": "更新",
|
||||
"upload": "アップロード",
|
||||
"openFile": "ファイルを開く",
|
||||
"stopSearch": "検索を停止",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
@@ -259,7 +258,8 @@
|
||||
"userManagement": "ユーザー管理",
|
||||
"userUpdated": "ユーザーを更新しました!",
|
||||
"username": "ユーザー名",
|
||||
"users": "ユーザー"
|
||||
"users": "ユーザー",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "ヘルプ",
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
"toggleSidebar": "사이드바 전환",
|
||||
"update": "업데이트",
|
||||
"upload": "업로드",
|
||||
"stopSearch": "검색 중지",
|
||||
"openFile": "파일 열기",
|
||||
"discardChanges": "변경 사항 취소",
|
||||
"stopSearch": "Stop searching",
|
||||
@@ -259,7 +258,8 @@
|
||||
"userManagement": "사용자 관리",
|
||||
"userUpdated": "사용자 수정됨!",
|
||||
"username": "사용자 이름",
|
||||
"users": "사용자"
|
||||
"users": "사용자",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "도움말",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Lietotāju pārvaldība",
|
||||
"userUpdated": "Lietotājs atjaunināts!",
|
||||
"username": "Lietotājvārds",
|
||||
"users": "Lietotāji"
|
||||
"users": "Lietotāji",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Palīdzība",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Lietotāju pārvaldība",
|
||||
"userUpdated": "Lietotājs atjaunināts!",
|
||||
"username": "Lietotājvārds",
|
||||
"users": "Lietotāji"
|
||||
"users": "Lietotāji",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Palīdzība",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Gebruikersbeheer",
|
||||
"userUpdated": "Gebruiker bijgewerkt!",
|
||||
"username": "Gebruikersnaam",
|
||||
"users": "Gebruikers"
|
||||
"users": "Gebruikers",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Help",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Brukeradministrasjon",
|
||||
"userUpdated": "Bruker opprettet!",
|
||||
"username": "Brukernavn",
|
||||
"users": "Bruker"
|
||||
"users": "Bruker",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hjelp",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Zarządzanie użytkownikami",
|
||||
"userUpdated": "Użytkownik zapisany!",
|
||||
"username": "Nazwa użytkownika",
|
||||
"users": "Użytkownicy"
|
||||
"users": "Użytkownicy",
|
||||
"currentPassword": "Twoje aktualne hasło"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Pomoc",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Gerenciamento de usuários",
|
||||
"userUpdated": "Usuário atualizado!",
|
||||
"username": "Nome do usuário",
|
||||
"users": "Usuários"
|
||||
"users": "Usuários",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ajuda",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Gestão de utilizadores",
|
||||
"userUpdated": "Utilizador atualizado!",
|
||||
"username": "Nome de utilizador",
|
||||
"users": "Utilizadores"
|
||||
"users": "Utilizadores",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ajuda",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Gestionare utilizatori",
|
||||
"userUpdated": "Utilizator actualizat!",
|
||||
"username": "Utilizator",
|
||||
"users": "Utilizatori"
|
||||
"users": "Utilizatori",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ajutor",
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
"update": "Обновить",
|
||||
"upload": "Загрузить",
|
||||
"openFile": "Открыть файл",
|
||||
"stopSearch": "Прекратить поиск",
|
||||
"discardChanges": "Отказаться",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Сохранить",
|
||||
@@ -259,7 +258,8 @@
|
||||
"userManagement": "Управление пользователями",
|
||||
"userUpdated": "Пользователь изменен!",
|
||||
"username": "Имя пользователя",
|
||||
"users": "Пользователи"
|
||||
"users": "Пользователи",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Помощь",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Správa používateľov",
|
||||
"userUpdated": "Používateľ upravený!",
|
||||
"username": "Meno používateľa",
|
||||
"users": "Používatelia"
|
||||
"users": "Používatelia",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Pomoc",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Användarehantering",
|
||||
"userUpdated": "Användare uppdaterad!",
|
||||
"username": "Användarnamn",
|
||||
"users": "Användare"
|
||||
"users": "Användare",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hjälp",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Kullanıcı yönetimi",
|
||||
"userUpdated": "Kullanıcı güncellendi!",
|
||||
"username": "Kullanıcı adı",
|
||||
"users": "Kullanıcılar"
|
||||
"users": "Kullanıcılar",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Yardım",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Керування користувачами",
|
||||
"userUpdated": "Користувача змінено!",
|
||||
"username": "Ім'я користувача",
|
||||
"users": "Користувачі"
|
||||
"users": "Користувачі",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Допомога",
|
||||
|
||||
@@ -258,7 +258,8 @@
|
||||
"userManagement": "Quản lý người dùng",
|
||||
"userUpdated": "Người dùng đã được cập nhật!",
|
||||
"username": "Tên người dùng",
|
||||
"users": "Người dùng"
|
||||
"users": "Người dùng",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Trợ giúp",
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
"update": "更新",
|
||||
"upload": "上传",
|
||||
"openFile": "打开文件",
|
||||
"stopSearch": "停止搜索",
|
||||
"discardChanges": "放弃更改",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "保存更改",
|
||||
@@ -259,7 +258,8 @@
|
||||
"userManagement": "用户管理",
|
||||
"userUpdated": "用户已更新!",
|
||||
"username": "用户名",
|
||||
"users": "用户"
|
||||
"users": "用户",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "帮助",
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
"update": "更新",
|
||||
"upload": "上傳",
|
||||
"openFile": "開啟檔案",
|
||||
"stopSearch": "停止搜尋",
|
||||
"discardChanges": "放棄變更",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
@@ -259,7 +258,8 @@
|
||||
"userManagement": "使用者管理",
|
||||
"userUpdated": "使用者已更新!",
|
||||
"username": "使用者名稱",
|
||||
"users": "使用者"
|
||||
"users": "使用者",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "幫助",
|
||||
|
||||
@@ -18,6 +18,7 @@ interface SettingsDefaults {
|
||||
locale: string;
|
||||
viewMode: ViewModeType;
|
||||
singleClick: boolean;
|
||||
redirectAfterCopyMove: boolean;
|
||||
sorting: Sorting;
|
||||
perm: Permissions;
|
||||
commands: any[];
|
||||
|
||||
+2
@@ -10,6 +10,7 @@ interface IUser {
|
||||
lockPassword: boolean;
|
||||
hideDotfiles: boolean;
|
||||
singleClick: boolean;
|
||||
redirectAfterCopyMove: boolean;
|
||||
dateFormat: boolean;
|
||||
viewMode: ViewModeType;
|
||||
sorting?: Sorting;
|
||||
@@ -30,6 +31,7 @@ interface IUserForm {
|
||||
lockPassword?: boolean;
|
||||
hideDotfiles?: boolean;
|
||||
singleClick?: boolean;
|
||||
redirectAfterCopyMove?: boolean;
|
||||
dateFormat?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
ref="listing"
|
||||
class="file-icons"
|
||||
:class="authStore.user?.viewMode ?? ''"
|
||||
@click="handleEmptyAreaClick"
|
||||
>
|
||||
<div>
|
||||
<div class="item header">
|
||||
@@ -1051,4 +1052,18 @@ const showContextMenu = (event: MouseEvent) => {
|
||||
const hideContextMenu = () => {
|
||||
isContextMenuVisible.value = false;
|
||||
};
|
||||
|
||||
const handleEmptyAreaClick = (e: MouseEvent) => {
|
||||
const target = e.target;
|
||||
if (!(target instanceof HTMLElement)) return;
|
||||
|
||||
if (target.closest("item") || target.closest(".item")) return;
|
||||
|
||||
fileStore.selected = [];
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
#listing {
|
||||
min-height: calc(100vh - 8rem);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
<input type="checkbox" name="singleClick" v-model="singleClick" />
|
||||
{{ t("settings.singleClick") }}
|
||||
</p>
|
||||
<p>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="redirectAfterCopyMove"
|
||||
v-model="redirectAfterCopyMove"
|
||||
/>
|
||||
{{ t("settings.redirectAfterCopyMove") }}
|
||||
</p>
|
||||
<p>
|
||||
<input type="checkbox" name="dateFormat" v-model="dateFormat" />
|
||||
{{ t("settings.setDateFormat") }}
|
||||
@@ -44,7 +52,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<div v-if="!noAuth" class="column">
|
||||
<form
|
||||
class="card"
|
||||
v-if="!authStore.user?.lockPassword"
|
||||
@@ -96,11 +104,12 @@
|
||||
<script setup lang="ts">
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { useLayoutStore } from "@/stores/layout";
|
||||
import { users as api, settings } from "@/api";
|
||||
import { users as api } from "@/api";
|
||||
import AceEditorTheme from "@/components/settings/AceEditorTheme.vue";
|
||||
import Languages from "@/components/settings/Languages.vue";
|
||||
import { computed, inject, onMounted, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { authMethod, noAuth } from "@/utils/constants";
|
||||
|
||||
const layoutStore = useLayoutStore();
|
||||
const authStore = useAuthStore();
|
||||
@@ -115,6 +124,7 @@ const currentPassword = ref<string>("");
|
||||
const isCurrentPasswordRequired = ref<boolean>(false);
|
||||
const hideDotfiles = ref<boolean>(false);
|
||||
const singleClick = ref<boolean>(false);
|
||||
const redirectAfterCopyMove = ref<boolean>(false);
|
||||
const dateFormat = ref<boolean>(false);
|
||||
const locale = ref<string>("");
|
||||
const aceEditorTheme = ref<string>("");
|
||||
@@ -139,10 +149,10 @@ onMounted(async () => {
|
||||
locale.value = authStore.user.locale;
|
||||
hideDotfiles.value = authStore.user.hideDotfiles;
|
||||
singleClick.value = authStore.user.singleClick;
|
||||
redirectAfterCopyMove.value = authStore.user.redirectAfterCopyMove;
|
||||
dateFormat.value = authStore.user.dateFormat;
|
||||
aceEditorTheme.value = authStore.user.aceEditorTheme;
|
||||
layoutStore.loading = false;
|
||||
const { authMethod } = await settings.get();
|
||||
isCurrentPasswordRequired.value = authMethod == "json";
|
||||
|
||||
return true;
|
||||
@@ -187,6 +197,7 @@ const updateSettings = async (event: Event) => {
|
||||
locale: locale.value,
|
||||
hideDotfiles: hideDotfiles.value,
|
||||
singleClick: singleClick.value,
|
||||
redirectAfterCopyMove: redirectAfterCopyMove.value,
|
||||
dateFormat: dateFormat.value,
|
||||
aceEditorTheme: aceEditorTheme.value,
|
||||
};
|
||||
@@ -195,6 +206,7 @@ const updateSettings = async (event: Event) => {
|
||||
"locale",
|
||||
"hideDotfiles",
|
||||
"singleClick",
|
||||
"redirectAfterCopyMove",
|
||||
"dateFormat",
|
||||
"aceEditorTheme",
|
||||
]);
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ require (
|
||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/image v0.34.0
|
||||
golang.org/x/text v0.32.0
|
||||
golang.org/x/text v0.33.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
+2
-2
@@ -372,8 +372,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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
+24
-22
@@ -23,17 +23,18 @@ const (
|
||||
)
|
||||
|
||||
type userInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
Username string `json:"username"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
ID uint `json:"id"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
RedirectAfterCopyMove bool `json:"redirectAfterCopyMove"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
Username string `json:"username"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
}
|
||||
|
||||
type authToken struct {
|
||||
@@ -204,17 +205,18 @@ func renewHandler(tokenExpireTime time.Duration) handleFunc {
|
||||
func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User, tokenExpirationTime time.Duration) (int, error) {
|
||||
claims := &authToken{
|
||||
User: userInfo{
|
||||
ID: user.ID,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
Perm: user.Perm,
|
||||
LockPassword: user.LockPassword,
|
||||
Commands: user.Commands,
|
||||
HideDotfiles: user.HideDotfiles,
|
||||
DateFormat: user.DateFormat,
|
||||
Username: user.Username,
|
||||
AceEditorTheme: user.AceEditorTheme,
|
||||
ID: user.ID,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
RedirectAfterCopyMove: user.RedirectAfterCopyMove,
|
||||
Perm: user.Perm,
|
||||
LockPassword: user.LockPassword,
|
||||
Commands: user.Commands,
|
||||
HideDotfiles: user.HideDotfiles,
|
||||
DateFormat: user.DateFormat,
|
||||
Username: user.Username,
|
||||
AceEditorTheme: user.AceEditorTheme,
|
||||
},
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
|
||||
@@ -280,6 +280,12 @@ func writeFile(afs afero.Fs, dst string, in io.Reader, fileMode, dirMode fs.File
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Sync the file to ensure all data is written to storage.
|
||||
// to prevent file corruption.
|
||||
if err := file.Sync(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Gets the info about the file.
|
||||
info, err := file.Stat()
|
||||
if err != nil {
|
||||
|
||||
@@ -256,6 +256,12 @@ func tusPatchHandler() handleFunc {
|
||||
return http.StatusInternalServerError, fmt.Errorf("could not write to file: %w", err)
|
||||
}
|
||||
|
||||
// Sync the file to ensure all data is written to storage
|
||||
// to prevent file corruption.
|
||||
if err := openFile.Sync(); err != nil {
|
||||
return http.StatusInternalServerError, fmt.Errorf("could not sync file: %w", err)
|
||||
}
|
||||
|
||||
newOffset := uploadOffset + bytesWritten
|
||||
w.Header().Set("Upload-Offset", strconv.FormatInt(newOffset, 10))
|
||||
|
||||
|
||||
@@ -8,16 +8,17 @@ import (
|
||||
// UserDefaults is a type that holds the default values
|
||||
// for some fields on User.
|
||||
type UserDefaults struct {
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
RedirectAfterCopyMove bool `json:"redirectAfterCopyMove"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
}
|
||||
|
||||
// Apply applies the default options to a user.
|
||||
@@ -26,6 +27,7 @@ func (d *UserDefaults) Apply(u *users.User) {
|
||||
u.Locale = d.Locale
|
||||
u.ViewMode = d.ViewMode
|
||||
u.SingleClick = d.SingleClick
|
||||
u.RedirectAfterCopyMove = d.RedirectAfterCopyMove
|
||||
u.Perm = d.Perm
|
||||
u.Sorting = d.Sorting
|
||||
u.Commands = d.Commands
|
||||
|
||||
+17
-16
@@ -20,22 +20,23 @@ const (
|
||||
|
||||
// User describes a user.
|
||||
type User struct {
|
||||
ID uint `storm:"id,increment" json:"id"`
|
||||
Username string `storm:"unique" json:"username"`
|
||||
Password string `json:"password"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
ViewMode ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Fs afero.Fs `json:"-" yaml:"-"`
|
||||
Rules []rules.Rule `json:"rules"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
ID uint `storm:"id,increment" json:"id"`
|
||||
Username string `storm:"unique" json:"username"`
|
||||
Password string `json:"password"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
ViewMode ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
RedirectAfterCopyMove bool `json:"redirectAfterCopyMove"`
|
||||
Perm Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Fs afero.Fs `json:"-" yaml:"-"`
|
||||
Rules []rules.Rule `json:"rules"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
}
|
||||
|
||||
// GetRules implements rules.Provider.
|
||||
|
||||
@@ -61,6 +61,7 @@ filebrowser config init [flags]
|
||||
--recaptcha.host string use another host for ReCAPTCHA. recaptcha.net might be useful in China (default "https://www.google.com")
|
||||
--recaptcha.key string ReCaptcha site key
|
||||
--recaptcha.secret string ReCaptcha secret
|
||||
--redirectAfterCopyMove redirect to destination after copy/move
|
||||
-r, --root string root to prepend to relative paths (default ".")
|
||||
--scope string scope for users (default ".")
|
||||
--shell string shell command to which other commands should be appended
|
||||
|
||||
@@ -58,6 +58,7 @@ filebrowser config set [flags]
|
||||
--recaptcha.host string use another host for ReCAPTCHA. recaptcha.net might be useful in China (default "https://www.google.com")
|
||||
--recaptcha.key string ReCaptcha site key
|
||||
--recaptcha.secret string ReCaptcha secret
|
||||
--redirectAfterCopyMove redirect to destination after copy/move
|
||||
-r, --root string root to prepend to relative paths (default ".")
|
||||
--scope string scope for users (default ".")
|
||||
--shell string shell command to which other commands should be appended
|
||||
|
||||
@@ -28,6 +28,7 @@ filebrowser users add <username> <password> [flags]
|
||||
--perm.modify modify perm for users (default true)
|
||||
--perm.rename rename perm for users (default true)
|
||||
--perm.share share perm for users (default true)
|
||||
--redirectAfterCopyMove redirect to destination after copy/move
|
||||
--scope string scope for users (default ".")
|
||||
--singleClick use single clicks only
|
||||
--sorting.asc sorting by ascending order
|
||||
|
||||
@@ -30,6 +30,7 @@ filebrowser users update <id|username> [flags]
|
||||
--perm.modify modify perm for users (default true)
|
||||
--perm.rename rename perm for users (default true)
|
||||
--perm.share share perm for users (default true)
|
||||
--redirectAfterCopyMove redirect to destination after copy/move
|
||||
--scope string scope for users (default ".")
|
||||
--singleClick use single clicks only
|
||||
--sorting.asc sorting by ascending order
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# 简介
|
||||
# GeoIP 简介 [](https://deepwiki.com/Loyalsoldier/geoip)
|
||||
|
||||
本项目每周四自动生成多种格式 GeoIP 文件,同时提供命令行界面(CLI)工具供用户自行定制 GeoIP 文件,包括但不限于 V2Ray `dat` 格式文件 `geoip.dat`、MaxMind `mmdb` 格式文件 `Country.mmdb`、sing-box `SRS` 格式文件、mihomo `MRS` 格式文件、Clash ruleset 和 Surge ruleset。
|
||||
|
||||
|
||||
@@ -21,8 +21,13 @@ WORKDIR /test
|
||||
|
||||
# Copy binaries, data and test script into the container.
|
||||
COPY bin/sing-box bin/mita bin/httpserver bin/sockshttpclient bin/socksudpclient bin/udpserver \
|
||||
test/deploy/singbox/client_tcp.json \
|
||||
test/deploy/singbox/client_tcp_no_wait.json \
|
||||
test/deploy/singbox/client_udp.json \
|
||||
test/deploy/singbox/client_udp_no_wait.json \
|
||||
test/deploy/singbox/singbox-client-config-tcp.json \
|
||||
test/deploy/singbox/singbox-client-config-udp.json \
|
||||
test/deploy/singbox/singbox-server-config.json \
|
||||
test/deploy/singbox/server_tcp.json \
|
||||
test/deploy/singbox/server_udp.json \
|
||||
test/deploy/singbox/libtest.sh \
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"profiles": [
|
||||
{
|
||||
"profileName": "default",
|
||||
"user": {
|
||||
"name": "baozi",
|
||||
"password": "manlianpenfen"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"ipAddress": "127.0.0.1",
|
||||
"portBindings": [
|
||||
{
|
||||
"port": 8966,
|
||||
"protocol": "TCP"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"multiplexing": {
|
||||
"level": "MULTIPLEXING_HIGH"
|
||||
}
|
||||
}
|
||||
],
|
||||
"activeProfile": "default",
|
||||
"rpcPort": 8989,
|
||||
"socks5Port": 1082,
|
||||
"advancedSettings": {
|
||||
"noCheckUpdate": true
|
||||
},
|
||||
"loggingLevel": "INFO"
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"profiles": [
|
||||
{
|
||||
"profileName": "default",
|
||||
"user": {
|
||||
"name": "baozi",
|
||||
"password": "manlianpenfen"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"ipAddress": "127.0.0.1",
|
||||
"portBindings": [
|
||||
{
|
||||
"port": 8966,
|
||||
"protocol": "TCP"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"multiplexing": {
|
||||
"level": "MULTIPLEXING_HIGH"
|
||||
},
|
||||
"handshakeMode": "HANDSHAKE_NO_WAIT"
|
||||
}
|
||||
],
|
||||
"activeProfile": "default",
|
||||
"rpcPort": 8989,
|
||||
"socks5Port": 1082,
|
||||
"advancedSettings": {
|
||||
"noCheckUpdate": true
|
||||
},
|
||||
"loggingLevel": "INFO"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"profiles": [
|
||||
{
|
||||
"profileName": "default",
|
||||
"user": {
|
||||
"name": "baozi",
|
||||
"password": "manlianpenfen"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"ipAddress": "127.0.0.1",
|
||||
"portBindings": [
|
||||
{
|
||||
"port": 8966,
|
||||
"protocol": "UDP"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"multiplexing": {
|
||||
"level": "MULTIPLEXING_HIGH"
|
||||
}
|
||||
}
|
||||
],
|
||||
"activeProfile": "default",
|
||||
"rpcPort": 8989,
|
||||
"socks5Port": 1085,
|
||||
"advancedSettings": {
|
||||
"noCheckUpdate": true
|
||||
},
|
||||
"loggingLevel": "INFO"
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"profiles": [
|
||||
{
|
||||
"profileName": "default",
|
||||
"user": {
|
||||
"name": "baozi",
|
||||
"password": "manlianpenfen"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"ipAddress": "127.0.0.1",
|
||||
"portBindings": [
|
||||
{
|
||||
"port": 8966,
|
||||
"protocol": "UDP"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"multiplexing": {
|
||||
"level": "MULTIPLEXING_HIGH"
|
||||
},
|
||||
"handshakeMode": "HANDSHAKE_NO_WAIT"
|
||||
}
|
||||
],
|
||||
"activeProfile": "default",
|
||||
"rpcPort": 8989,
|
||||
"socks5Port": 1085,
|
||||
"advancedSettings": {
|
||||
"noCheckUpdate": true
|
||||
},
|
||||
"loggingLevel": "INFO"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "mieru",
|
||||
"tag": "mieru-tcp",
|
||||
"listen": "127.0.0.1",
|
||||
"listen_port": 8966,
|
||||
"transport": "TCP",
|
||||
"users": [
|
||||
{
|
||||
"name": "baozi",
|
||||
"password": "manlianpenfen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "mieru",
|
||||
"tag": "mieru-udp",
|
||||
"listen": "127.0.0.1",
|
||||
"listen_port": 8966,
|
||||
"transport": "UDP",
|
||||
"users": [
|
||||
{
|
||||
"name": "baozi",
|
||||
"password": "manlianpenfen"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outbounds": [],
|
||||
"route": {},
|
||||
"log": {
|
||||
"level": "warn"
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=filebrowser
|
||||
PKG_VERSION:=2.53.1
|
||||
PKG_VERSION:=2.54.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/filebrowser/filebrowser/tar.gz/v${PKG_VERSION}?
|
||||
PKG_HASH:=68f55a90cf25c4e147dc50d45de2a619f4b24e9c2f6fa7c7de05130ca0b4e123
|
||||
PKG_HASH:=0752cc7444e2f327cb4beefe6eb40493bfd2f5a077daa2e5dbf6ace013cfc34d
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
LUCI_TITLE:=LuCI support for ddnsto
|
||||
LUCI_DEPENDS:=+ddnsto +block-mount
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=3.2.0-r4
|
||||
PKG_VERSION:=3.2.0-r5
|
||||
PKG_RELEASE:=
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -4,10 +4,12 @@ local api = require "luci.passwall.api"
|
||||
<script src="<%=resource%>/view/<%=api.appname%>/Sortable.min.js?v=26.1.9"></script>
|
||||
|
||||
<style>
|
||||
<% if api.is_js_luci() then -%>
|
||||
table .cbi-button-up,
|
||||
table .cbi-button-down {
|
||||
display: none !important;
|
||||
}
|
||||
<%- end %>
|
||||
|
||||
.drag-handle {
|
||||
cursor: grab !important;
|
||||
|
||||
@@ -166,6 +166,6 @@ o:value(0, translate("Primary"))
|
||||
o:value(1, translate("Standby"))
|
||||
o.rmempty = false
|
||||
|
||||
s:append(Template(appname .. "/haproxy/js"))
|
||||
m:append(Template(appname .. "/haproxy/js"))
|
||||
|
||||
return m
|
||||
|
||||
@@ -1,4 +1,35 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
-%>
|
||||
<script src="<%=resource%>/view/<%=api.appname%>/Sortable.min.js?v=26.1.9"></script>
|
||||
|
||||
<style>
|
||||
<% if api.is_js_luci() then -%>
|
||||
table .cbi-button-up,
|
||||
table .cbi-button-down {
|
||||
display: none !important;
|
||||
}
|
||||
<%- end %>
|
||||
|
||||
.drag-handle {
|
||||
cursor: grab !important;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-weight: 100;
|
||||
padding: 0 !important;
|
||||
line-height: inherit;
|
||||
user-select: none;
|
||||
color: #00000070;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.dragging-row {
|
||||
background-color: rgba(131, 191, 255, 0.7) !important;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
@@ -45,5 +76,97 @@
|
||||
}
|
||||
}, 300);
|
||||
});
|
||||
|
||||
//节点列表添加拖拽排序
|
||||
(function () {
|
||||
function initSortableForTable() {
|
||||
var section = document.getElementById("cbi-<%=api.appname%>-haproxy_config");
|
||||
if (!section) return;
|
||||
|
||||
// === 插入 drag handle ===
|
||||
var delBtns = section.getElementsByClassName("cbi-button-remove");
|
||||
for (var i = 0; i < delBtns.length; i++) {
|
||||
var btn = delBtns[i];
|
||||
var parent = btn && btn.parentNode;
|
||||
if (!parent || parent.getElementsByClassName("drag-handle").length)
|
||||
continue;
|
||||
var handle = document.createElement("span");
|
||||
handle.className = "drag-handle center";
|
||||
handle.title = "<%:Drag to reorder%>";
|
||||
handle.innerHTML = "⠿";
|
||||
parent.insertBefore(handle, btn.nextSibling);
|
||||
}
|
||||
|
||||
// === 初始化 Sortable ===
|
||||
var table = section.getElementsByTagName("table")[0];
|
||||
if (!table) return;
|
||||
var root = table.tBodies[0] || table;
|
||||
if (root._sortable_initialized) return root._sortable_instance;
|
||||
root._sortable_initialized = true;
|
||||
|
||||
// 保存原始顺序
|
||||
root._origOrder = getCurrentOrder(root);
|
||||
|
||||
try {
|
||||
root._sortable_instance = Sortable.create(root, {
|
||||
handle: ".drag-handle",
|
||||
draggable: "tr.cbi-section-table-row",
|
||||
animation: 150,
|
||||
ghostClass: "dragging-row",
|
||||
fallbackOnBody: true,
|
||||
forceFallback: false,
|
||||
swapThreshold: 0.65,
|
||||
onEnd: function (evt) {
|
||||
updateHiddenInput(root, section);
|
||||
}
|
||||
});
|
||||
return root._sortable_instance;
|
||||
} catch (e) {
|
||||
root._sortable_initialized = false;
|
||||
console.error("Sortable init failed:", e);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取 table 当前行顺序
|
||||
function getCurrentOrder(root) {
|
||||
var order = [];
|
||||
var rows = root.querySelectorAll("tr.cbi-section-table-row");
|
||||
rows.forEach(function (tr) {
|
||||
var id = tr.id || "";
|
||||
if (id.startsWith("cbi-<%=api.appname%>-"))
|
||||
id = id.replace("cbi-<%=api.appname%>-", "");
|
||||
order.push(id);
|
||||
});
|
||||
return order;
|
||||
}
|
||||
|
||||
// 拖拽完成后更新 hidden input
|
||||
function updateHiddenInput(root, section) {
|
||||
var newOrder = getCurrentOrder(root);
|
||||
var changed = newOrder.join(" ") !== root._origOrder.join(" ");
|
||||
var hiddenInput = section.querySelector('input[type="hidden"][id^="cbi.sts."]');
|
||||
if (hiddenInput) {
|
||||
hiddenInput.value = changed ? newOrder.join(" ") : "";
|
||||
}
|
||||
}
|
||||
|
||||
// === 等待 TypedSection 行稳定 ===
|
||||
(function waitStable() {
|
||||
var last = 0, stable = 0;
|
||||
var THRESHOLD = 5;
|
||||
function tick() {
|
||||
var count = document.querySelectorAll("tr.cbi-section-table-row").length;
|
||||
if (count && count === last) stable++;
|
||||
else stable = 0;
|
||||
|
||||
last = count;
|
||||
if (stable >= THRESHOLD)
|
||||
initSortableForTable();
|
||||
else
|
||||
requestAnimationFrame(tick);
|
||||
}
|
||||
tick();
|
||||
})();
|
||||
})();
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
-%>
|
||||
<script src="<%=resource%>/view/<%=api.appname%>/Sortable.min.js?v=26.1.9"></script>
|
||||
|
||||
<style>
|
||||
div.cbi-value[id$="-gfwlist_update"],
|
||||
@@ -11,6 +12,25 @@ local api = require "luci.passwall.api"
|
||||
div.cbi-value[id$="-geosite_update"] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.drag-handle {
|
||||
cursor: grab !important;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-weight: 100;
|
||||
padding: 0 !important;
|
||||
line-height: inherit;
|
||||
user-select: none;
|
||||
color: #00000070;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.dragging-row {
|
||||
background-color: rgba(131, 191, 255, 0.7) !important;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="cbi-value" id="_rule_div">
|
||||
@@ -116,5 +136,97 @@ local api = require "luci.passwall.api"
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//分流规则添加拖拽排序
|
||||
(function () {
|
||||
function initSortableForTable() {
|
||||
var section = document.getElementById("cbi-<%=api.appname%>-shunt_rules");
|
||||
if (!section) return;
|
||||
|
||||
// === 插入 drag handle ===
|
||||
var delBtns = section.getElementsByClassName("cbi-button-remove");
|
||||
for (var i = 0; i < delBtns.length; i++) {
|
||||
var btn = delBtns[i];
|
||||
var parent = btn && btn.parentNode;
|
||||
if (!parent || parent.getElementsByClassName("drag-handle").length)
|
||||
continue;
|
||||
var handle = document.createElement("span");
|
||||
handle.className = "drag-handle center";
|
||||
handle.title = "<%:Drag to reorder%>";
|
||||
handle.innerHTML = "⠿";
|
||||
parent.insertBefore(handle, btn.nextSibling);
|
||||
}
|
||||
|
||||
// === 初始化 Sortable ===
|
||||
var table = section.getElementsByTagName("table")[0];
|
||||
if (!table) return;
|
||||
var root = table.tBodies[0] || table;
|
||||
if (root._sortable_initialized) return root._sortable_instance;
|
||||
root._sortable_initialized = true;
|
||||
|
||||
// 保存原始顺序
|
||||
root._origOrder = getCurrentOrder(root);
|
||||
|
||||
try {
|
||||
root._sortable_instance = Sortable.create(root, {
|
||||
handle: ".drag-handle",
|
||||
draggable: "tr.cbi-section-table-row",
|
||||
animation: 150,
|
||||
ghostClass: "dragging-row",
|
||||
fallbackOnBody: true,
|
||||
forceFallback: false,
|
||||
swapThreshold: 0.65,
|
||||
onEnd: function (evt) {
|
||||
updateHiddenInput(root, section);
|
||||
}
|
||||
});
|
||||
return root._sortable_instance;
|
||||
} catch (e) {
|
||||
root._sortable_initialized = false;
|
||||
console.error("Sortable init failed:", e);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取 table 当前行顺序
|
||||
function getCurrentOrder(root) {
|
||||
var order = [];
|
||||
var rows = root.querySelectorAll("tr.cbi-section-table-row");
|
||||
rows.forEach(function (tr) {
|
||||
var id = tr.id || "";
|
||||
if (id.startsWith("cbi-<%=api.appname%>-"))
|
||||
id = id.replace("cbi-<%=api.appname%>-", "");
|
||||
order.push(id);
|
||||
});
|
||||
return order;
|
||||
}
|
||||
|
||||
// 拖拽完成后更新 hidden input
|
||||
function updateHiddenInput(root, section) {
|
||||
var newOrder = getCurrentOrder(root);
|
||||
var changed = newOrder.join(" ") !== root._origOrder.join(" ");
|
||||
var hiddenInput = section.querySelector('input[type="hidden"][id^="cbi.sts."]');
|
||||
if (hiddenInput) {
|
||||
hiddenInput.value = changed ? newOrder.join(" ") : "";
|
||||
}
|
||||
}
|
||||
|
||||
// === 等待 TypedSection 行稳定 ===
|
||||
(function waitStable() {
|
||||
var last = 0, stable = 0;
|
||||
var THRESHOLD = 5;
|
||||
function tick() {
|
||||
var count = document.querySelectorAll("tr.cbi-section-table-row").length;
|
||||
if (count && count === last) stable++;
|
||||
else stable = 0;
|
||||
|
||||
last = count;
|
||||
if (stable >= THRESHOLD)
|
||||
initSortableForTable();
|
||||
else
|
||||
requestAnimationFrame(tick);
|
||||
}
|
||||
tick();
|
||||
})();
|
||||
})();
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
@@ -691,7 +691,7 @@ run_socks() {
|
||||
|
||||
case "$type" in
|
||||
socks)
|
||||
local _socks_address _socks_port _socks_username _socks_password _extra_param microsocks_fwd
|
||||
local _socks_address _socks_port _socks_username _socks_password
|
||||
if [ "$node2socks_port" = "0" ]; then
|
||||
_socks_address=$(config_n_get $node address)
|
||||
_socks_port=$(config_n_get $node port)
|
||||
@@ -701,24 +701,13 @@ run_socks() {
|
||||
_socks_address="127.0.0.1"
|
||||
_socks_port=$node2socks_port
|
||||
fi
|
||||
if [ "$http_port" != "0" ]; then
|
||||
[ "$http_port" != "0" ] && {
|
||||
http_flag=1
|
||||
config_file="${config_file//SOCKS/HTTP_SOCKS}"
|
||||
_extra_param="-local_http_address $bind -local_http_port $http_port"
|
||||
else
|
||||
# 仅 passwall-packages 专用的 microsocks 才支持 socks 转发规则!
|
||||
microsocks_fwd="$($(first_type microsocks) -V 2>/dev/null | grep -i forward)"
|
||||
fi
|
||||
local _extra_param="-local_http_address $bind -local_http_port $http_port"
|
||||
}
|
||||
local bin=$(first_type $(config_t_get global_app sing_box_file) sing-box)
|
||||
if [ -n "$microsocks_fwd" ]; then
|
||||
local ext_name=$(echo "$config_file" | sed "s|^${TMP_PATH}/||; s|\.json\$||; s|/|_|g")
|
||||
if [ -n "$_socks_username" ] && [ -n "$_socks_password" ]; then
|
||||
_extra_param="-f \"0.0.0.0:0,${_socks_username}:${_socks_password}@${_socks_address}:${_socks_port},0.0.0.0:0\""
|
||||
else
|
||||
_extra_param="-f \"0.0.0.0:0,${_socks_address}:${_socks_port},0.0.0.0:0\""
|
||||
fi
|
||||
ln_run "$(first_type microsocks)" "microsocks_${ext_name}" $log_file -i $bind -p $socks_port ${_extra_param}
|
||||
elif [ -n "$bin" ]; then
|
||||
if [ -n "$bin" ]; then
|
||||
type="sing-box"
|
||||
lua $UTIL_SINGBOX gen_proto_config -local_socks_address $bind -local_socks_port $socks_port ${_extra_param} -server_proto socks -server_address ${_socks_address} -server_port ${_socks_port} -server_username ${_socks_username} -server_password ${_socks_password} > $config_file
|
||||
ln_run "$bin" ${type} $log_file run -c "$config_file"
|
||||
|
||||
@@ -21,13 +21,13 @@ define Download/geoip
|
||||
HASH:=ed2de9add79623e2e5dbc5930ee39cc7037a7c6e0ecd58ba528b6f73d61457b5
|
||||
endef
|
||||
|
||||
GEOSITE_VER:=20260109015452
|
||||
GEOSITE_VER:=20260110084845
|
||||
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
|
||||
define Download/geosite
|
||||
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
|
||||
URL_FILE:=dlc.dat
|
||||
FILE:=$(GEOSITE_FILE)
|
||||
HASH:=379bee918c0241df853bac6855d0fafa188c6cae262fc6c9639f1afcd5f6121e
|
||||
HASH:=274d189c37b7af64bd14d4ac76bc05a56683d9b502e01bc68a34df25711e11f1
|
||||
endef
|
||||
|
||||
GEOSITE_IRAN_VER:=202601050049
|
||||
|
||||
@@ -56,7 +56,8 @@ public class ProfilesViewModel : MyReactiveObject
|
||||
|
||||
public ReactiveCommand<Unit, Unit> MoveUpCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> MoveDownCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> MoveBottomCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> MoveBottomCmd { get; }
|
||||
public ReactiveCommand<SubItem, Unit> MoveToGroupCmd { get; }
|
||||
|
||||
//servers ping
|
||||
public ReactiveCommand<Unit, Unit> MixedTestServerCmd { get; }
|
||||
@@ -179,6 +180,10 @@ public class ProfilesViewModel : MyReactiveObject
|
||||
{
|
||||
await MoveServer(EMove.Bottom);
|
||||
}, canEditRemove);
|
||||
MoveToGroupCmd = ReactiveCommand.CreateFromTask<SubItem>(async sub =>
|
||||
{
|
||||
SelectedMoveToGroup = sub;
|
||||
});
|
||||
|
||||
//servers ping
|
||||
FastRealPingCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
x:Name="Root"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:DataType="vms:ProfilesViewModel"
|
||||
@@ -141,19 +142,18 @@
|
||||
InputGesture="Ctrl+T" />
|
||||
<MenuItem x:Name="menuSortServerResult" Header="{x:Static resx:ResUI.menuSortServerResult}" />
|
||||
<Separator />
|
||||
<MenuItem x:Name="menuMoveToGroup" Header="{x:Static resx:ResUI.menuMoveToGroup}">
|
||||
<MenuItem>
|
||||
<MenuItem.Header>
|
||||
<DockPanel>
|
||||
<ComboBox
|
||||
x:Name="cmbMoveToGroup"
|
||||
Width="200"
|
||||
DisplayMemberBinding="{Binding Remarks}"
|
||||
ItemsSource="{Binding SubItems}"
|
||||
ToolTip.Tip="{x:Static resx:ResUI.menuSubscription}" />
|
||||
</DockPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
x:Name="menuMoveToGroup"
|
||||
Header="{x:Static resx:ResUI.menuMoveToGroup}"
|
||||
ItemsSource="{Binding DataContext.SubItems, ElementName=Root}">
|
||||
<MenuItem.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<MenuItem
|
||||
Command="{Binding DataContext.MoveToGroupCmd, ElementName=Root}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{Binding Remarks}" />
|
||||
</DataTemplate>
|
||||
</MenuItem.ItemTemplate>
|
||||
</MenuItem>
|
||||
<MenuItem Header="{x:Static resx:ResUI.menuMoveTo}">
|
||||
<MenuItem
|
||||
|
||||
@@ -69,7 +69,7 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
|
||||
|
||||
//servers move
|
||||
//this.OneWayBind(ViewModel, vm => vm.SubItems, v => v.cmbMoveToGroup.ItemsSource).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedMoveToGroup, v => v.cmbMoveToGroup.SelectedItem).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.SelectedMoveToGroup, v => v.cmbMoveToGroup.SelectedItem).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.MoveTopCmd, v => v.menuMoveTop).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.MoveUpCmd, v => v.menuMoveUp).DisposeWith(disposables);
|
||||
|
||||
@@ -34,6 +34,8 @@ class AngApplication : MultiDexApplication() {
|
||||
|
||||
MMKV.initialize(this)
|
||||
|
||||
// Ensure critical preference defaults are present in MMKV early
|
||||
SettingsManager.ensureDefaultSettings()
|
||||
SettingsManager.setNightMode()
|
||||
// Initialize WorkManager with the custom configuration
|
||||
WorkManager.initialize(this, workManagerConfiguration)
|
||||
|
||||
@@ -493,6 +493,28 @@ object MmkvManager {
|
||||
return settingsStorage.encode(key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the settings.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param value The settings value.
|
||||
* @return Whether the encoding was successful.
|
||||
*/
|
||||
fun encodeSettings(key: String, value: Long): Boolean {
|
||||
return settingsStorage.encode(key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the settings.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param value The settings value.
|
||||
* @return Whether the encoding was successful.
|
||||
*/
|
||||
fun encodeSettings(key: String, value: Float): Boolean {
|
||||
return settingsStorage.encode(key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the settings.
|
||||
*
|
||||
@@ -536,6 +558,39 @@ object MmkvManager {
|
||||
return settingsStorage.decodeString(key, defaultValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the settings integer.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param defaultValue The default value.
|
||||
* @return The settings value.
|
||||
*/
|
||||
fun decodeSettingsInt(key: String, defaultValue: Int): Int {
|
||||
return settingsStorage.decodeInt(key, defaultValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the settings long.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param defaultValue The default value.
|
||||
* @return The settings value.
|
||||
*/
|
||||
fun decodeSettingsLong(key: String, defaultValue: Long): Long {
|
||||
return settingsStorage.decodeLong(key, defaultValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the settings float.
|
||||
*
|
||||
* @param key The settings key.
|
||||
* @param defaultValue The default value.
|
||||
* @return The settings value.
|
||||
*/
|
||||
fun decodeSettingsFloat(key: String, defaultValue: Float): Float {
|
||||
return settingsStorage.decodeFloat(key, defaultValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the settings boolean.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.v2ray.ang.handler
|
||||
|
||||
import androidx.preference.PreferenceDataStore
|
||||
import com.v2ray.ang.AppConfig
|
||||
|
||||
/**
|
||||
* PreferenceDataStore implementation that bridges AndroidX Preference framework to MMKV storage.
|
||||
* This ensures that all Preference UI operations read/write directly from/to MMKV,
|
||||
* avoiding inconsistencies between SharedPreferences and MMKV.
|
||||
*/
|
||||
class MmkvPreferenceDataStore : PreferenceDataStore() {
|
||||
|
||||
override fun putString(key: String, value: String?) {
|
||||
MmkvManager.encodeSettings(key, value)
|
||||
notifySettingChanged(key)
|
||||
}
|
||||
|
||||
override fun getString(key: String, defaultValue: String?): String? {
|
||||
return MmkvManager.decodeSettingsString(key, defaultValue)
|
||||
}
|
||||
|
||||
override fun putInt(key: String, value: Int) {
|
||||
MmkvManager.encodeSettings(key, value)
|
||||
notifySettingChanged(key)
|
||||
}
|
||||
|
||||
override fun getInt(key: String, defaultValue: Int): Int {
|
||||
return MmkvManager.decodeSettingsInt(key, defaultValue)
|
||||
}
|
||||
|
||||
override fun putLong(key: String, value: Long) {
|
||||
MmkvManager.encodeSettings(key, value)
|
||||
notifySettingChanged(key)
|
||||
}
|
||||
|
||||
override fun getLong(key: String, defaultValue: Long): Long {
|
||||
return MmkvManager.decodeSettingsLong(key, defaultValue)
|
||||
}
|
||||
|
||||
override fun putFloat(key: String, value: Float) {
|
||||
MmkvManager.encodeSettings(key, value)
|
||||
notifySettingChanged(key)
|
||||
}
|
||||
|
||||
override fun getFloat(key: String, defaultValue: Float): Float {
|
||||
return MmkvManager.decodeSettingsFloat(key, defaultValue)
|
||||
}
|
||||
|
||||
override fun putBoolean(key: String, value: Boolean) {
|
||||
MmkvManager.encodeSettings(key, value)
|
||||
notifySettingChanged(key)
|
||||
}
|
||||
|
||||
override fun getBoolean(key: String, defaultValue: Boolean): Boolean {
|
||||
return MmkvManager.decodeSettingsBool(key, defaultValue)
|
||||
}
|
||||
|
||||
override fun putStringSet(key: String, values: MutableSet<String>?) {
|
||||
if (values == null) {
|
||||
MmkvManager.encodeSettings(key, null as String?)
|
||||
} else {
|
||||
MmkvManager.encodeSettings(key, values)
|
||||
}
|
||||
notifySettingChanged(key)
|
||||
}
|
||||
|
||||
override fun getStringSet(key: String, defaultValues: MutableSet<String>?): MutableSet<String>? {
|
||||
return MmkvManager.decodeSettingsStringSet(key) ?: defaultValues
|
||||
}
|
||||
|
||||
// Internal helper: notify other modules about setting changes
|
||||
private fun notifySettingChanged(key: String) {
|
||||
// Call SettingsManager.setNightMode if UI mode changed
|
||||
if (key == AppConfig.PREF_UI_MODE_NIGHT) {
|
||||
SettingsManager.setNightMode()
|
||||
}
|
||||
// Notify listeners that require service restart or reinit
|
||||
SettingsChangeManager.makeRestartService()
|
||||
}
|
||||
}
|
||||
@@ -377,4 +377,31 @@ object SettingsManager {
|
||||
fun getVpnMtu(): Int {
|
||||
return Utils.parseInt(MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_MTU), AppConfig.VPN_MTU)
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure default settings are present in MMKV.
|
||||
*/
|
||||
fun ensureDefaultSettings() {
|
||||
// Write defaults in the exact order requested by the user
|
||||
ensureDefaultValue(AppConfig.PREF_MODE, AppConfig.VPN)
|
||||
ensureDefaultValue(AppConfig.PREF_VPN_DNS, AppConfig.DNS_VPN)
|
||||
ensureDefaultValue(AppConfig.PREF_VPN_MTU, AppConfig.VPN_MTU.toString())
|
||||
ensureDefaultValue(AppConfig.SUBSCRIPTION_AUTO_UPDATE_INTERVAL, AppConfig.SUBSCRIPTION_DEFAULT_UPDATE_INTERVAL)
|
||||
ensureDefaultValue(AppConfig.PREF_SOCKS_PORT, AppConfig.PORT_SOCKS.toString())
|
||||
ensureDefaultValue(AppConfig.PREF_REMOTE_DNS, AppConfig.DNS_PROXY)
|
||||
ensureDefaultValue(AppConfig.PREF_DOMESTIC_DNS, AppConfig.DNS_DIRECT)
|
||||
ensureDefaultValue(AppConfig.PREF_DELAY_TEST_URL, AppConfig.DELAY_TEST_URL)
|
||||
ensureDefaultValue(AppConfig.PREF_IP_API_URL, AppConfig.IP_API_URL)
|
||||
ensureDefaultValue(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT, AppConfig.HEVTUN_RW_TIMEOUT)
|
||||
ensureDefaultValue(AppConfig.PREF_MUX_CONCURRENCY, "8")
|
||||
ensureDefaultValue(AppConfig.PREF_MUX_XUDP_CONCURRENCY, "8")
|
||||
ensureDefaultValue(AppConfig.PREF_FRAGMENT_LENGTH, "50-100")
|
||||
ensureDefaultValue(AppConfig.PREF_FRAGMENT_INTERVAL, "10-20")
|
||||
}
|
||||
|
||||
private fun ensureDefaultValue(key: String, default: String) {
|
||||
if (MmkvManager.decodeSettingsString(key).isNullOrEmpty()) {
|
||||
MmkvManager.encodeSettings(key, default)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ class V2RayTestService : Service() {
|
||||
|
||||
// simple counter for currently running tasks
|
||||
private val realTestRunningCount = AtomicInteger(0)
|
||||
private val realTestCount = AtomicInteger(0)
|
||||
|
||||
/**
|
||||
* Initializes the V2Ray environment.
|
||||
@@ -56,15 +57,22 @@ class V2RayTestService : Service() {
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
when (intent?.getIntExtra("key", 0)) {
|
||||
MSG_MEASURE_CONFIG -> {
|
||||
val guid = intent.serializable<String>("content") ?: ""
|
||||
realTestScope.launch {
|
||||
realTestRunningCount.incrementAndGet()
|
||||
try {
|
||||
val result = startRealPing(guid)
|
||||
MessageUtil.sendMsg2UI(this@V2RayTestService, MSG_MEASURE_CONFIG_SUCCESS, Pair(guid, result))
|
||||
} finally {
|
||||
val left = realTestRunningCount.decrementAndGet()
|
||||
MessageUtil.sendMsg2UI(this@V2RayTestService, AppConfig.MSG_MEASURE_CONFIG_FINISH, left.toString())
|
||||
val guidsList = intent.serializable<ArrayList<String>>("content")
|
||||
if (guidsList == null || guidsList.isEmpty()) {
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
for (guid in guidsList) {
|
||||
realTestCount.incrementAndGet()
|
||||
realTestScope.launch {
|
||||
realTestRunningCount.incrementAndGet()
|
||||
try {
|
||||
val result = startRealPing(guid)
|
||||
MessageUtil.sendMsg2UI(this@V2RayTestService, MSG_MEASURE_CONFIG_SUCCESS, Pair(guid, result))
|
||||
} finally {
|
||||
val count = realTestCount.decrementAndGet()
|
||||
val left = realTestRunningCount.decrementAndGet()
|
||||
MessageUtil.sendMsg2UI(this@V2RayTestService, AppConfig.MSG_MEASURE_CONFIG_FINISH, "$left / $count")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.v2ray.ang.ui
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
|
||||
class FragmentAdapter(fragmentActivity: FragmentActivity, private val mFragments: List<Fragment>) :
|
||||
FragmentStateAdapter(fragmentActivity) {
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return mFragments[position]
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return mFragments.size
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package com.v2ray.ang.ui
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import androidx.activity.viewModels
|
||||
import androidx.preference.CheckBoxPreference
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.ListPreference
|
||||
@@ -17,20 +16,20 @@ import com.v2ray.ang.AppConfig.VPN
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.extension.toLongEx
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.handler.MmkvPreferenceDataStore
|
||||
import com.v2ray.ang.handler.SubscriptionUpdater
|
||||
import com.v2ray.ang.util.Utils
|
||||
import com.v2ray.ang.viewmodel.SettingsViewModel
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class SettingsActivity : BaseActivity() {
|
||||
private val settingsViewModel: SettingsViewModel by viewModels()
|
||||
//private val settingsViewModel: SettingsViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
//setContentView(R.layout.activity_settings)
|
||||
setContentViewWithToolbar(R.layout.activity_settings, showHomeAsUp = true, title = getString(R.string.title_settings))
|
||||
|
||||
settingsViewModel.startListenPreferenceChange()
|
||||
//settingsViewModel.startListenPreferenceChange()
|
||||
}
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
@@ -58,21 +57,27 @@ class SettingsActivity : BaseActivity() {
|
||||
private val autoUpdateCheck by lazy { findPreference<CheckBoxPreference>(AppConfig.SUBSCRIPTION_AUTO_UPDATE) }
|
||||
private val autoUpdateInterval by lazy { findPreference<EditTextPreference>(AppConfig.SUBSCRIPTION_AUTO_UPDATE_INTERVAL) }
|
||||
|
||||
private val socksPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_SOCKS_PORT) }
|
||||
private val remoteDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_REMOTE_DNS) }
|
||||
private val domesticDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DOMESTIC_DNS) }
|
||||
private val dnsHosts by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DNS_HOSTS) }
|
||||
private val delayTestUrl by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DELAY_TEST_URL) }
|
||||
private val ipApiUrl by lazy { findPreference<EditTextPreference>(AppConfig.PREF_IP_API_URL) }
|
||||
// private val socksPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_SOCKS_PORT) }
|
||||
// private val remoteDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_REMOTE_DNS) }
|
||||
// private val domesticDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DOMESTIC_DNS) }
|
||||
// private val dnsHosts by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DNS_HOSTS) }
|
||||
// private val delayTestUrl by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DELAY_TEST_URL) }
|
||||
// private val ipApiUrl by lazy { findPreference<EditTextPreference>(AppConfig.PREF_IP_API_URL) }
|
||||
private val mode by lazy { findPreference<ListPreference>(AppConfig.PREF_MODE) }
|
||||
|
||||
private val hevTunLogLevel by lazy { findPreference<ListPreference>(AppConfig.PREF_HEV_TUNNEL_LOGLEVEL) }
|
||||
private val hevTunRwTimeout by lazy { findPreference<EditTextPreference>(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT) }
|
||||
// private val hevTunLogLevel by lazy { findPreference<ListPreference>(AppConfig.PREF_HEV_TUNNEL_LOGLEVEL) }
|
||||
// private val hevTunRwTimeout by lazy { findPreference<EditTextPreference>(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT) }
|
||||
// private val useHevTun by lazy { findPreference<CheckBoxPreference>(AppConfig.PREF_USE_HEV_TUNNEL) }
|
||||
|
||||
override fun onCreatePreferences(bundle: Bundle?, s: String?) {
|
||||
// Use MMKV as the storage backend for all Preferences
|
||||
// This prevents inconsistencies between SharedPreferences and MMKV
|
||||
preferenceManager.preferenceDataStore = MmkvPreferenceDataStore()
|
||||
|
||||
addPreferencesFromResource(R.xml.pref_settings)
|
||||
|
||||
initPreferenceSummaries()
|
||||
|
||||
// perAppProxy?.setOnPreferenceClickListener {
|
||||
// startActivity(Intent(activity, PerAppProxyActivity::class.java))
|
||||
// perAppProxy?.isChecked = true
|
||||
@@ -87,16 +92,16 @@ class SettingsActivity : BaseActivity() {
|
||||
// localDnsPort?.summary = nval.ifEmpty { AppConfig.PORT_LOCAL_DNS }
|
||||
// true
|
||||
// }
|
||||
vpnDns?.setOnPreferenceChangeListener { _, any ->
|
||||
vpnDns?.summary = any as String
|
||||
true
|
||||
}
|
||||
// vpnDns?.setOnPreferenceChangeListener { _, any ->
|
||||
// vpnDns?.summary = any as String
|
||||
// true
|
||||
// }
|
||||
|
||||
vpnMtu?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
vpnMtu?.summary = nval.ifEmpty { AppConfig.VPN_MTU.toString() }
|
||||
true
|
||||
}
|
||||
// vpnMtu?.setOnPreferenceChangeListener { _, any ->
|
||||
// val nval = any as String
|
||||
// vpnMtu?.summary = nval.ifEmpty { AppConfig.VPN_MTU.toString() }
|
||||
// true
|
||||
// }
|
||||
|
||||
mux?.setOnPreferenceChangeListener { _, newValue ->
|
||||
updateMux(newValue as Boolean)
|
||||
@@ -115,18 +120,18 @@ class SettingsActivity : BaseActivity() {
|
||||
updateFragment(newValue as Boolean)
|
||||
true
|
||||
}
|
||||
fragmentPackets?.setOnPreferenceChangeListener { _, newValue ->
|
||||
updateFragmentPackets(newValue as String)
|
||||
true
|
||||
}
|
||||
fragmentLength?.setOnPreferenceChangeListener { _, newValue ->
|
||||
updateFragmentLength(newValue as String)
|
||||
true
|
||||
}
|
||||
fragmentInterval?.setOnPreferenceChangeListener { _, newValue ->
|
||||
updateFragmentInterval(newValue as String)
|
||||
true
|
||||
}
|
||||
// fragmentPackets?.setOnPreferenceChangeListener { _, newValue ->
|
||||
// updateFragmentPackets(newValue as String)
|
||||
// true
|
||||
// }
|
||||
// fragmentLength?.setOnPreferenceChangeListener { _, newValue ->
|
||||
// updateFragmentLength(newValue as String)
|
||||
// true
|
||||
// }
|
||||
// fragmentInterval?.setOnPreferenceChangeListener { _, newValue ->
|
||||
// updateFragmentInterval(newValue as String)
|
||||
// true
|
||||
// }
|
||||
|
||||
autoUpdateCheck?.setOnPreferenceChangeListener { _, newValue ->
|
||||
val value = newValue as Boolean
|
||||
@@ -137,48 +142,48 @@ class SettingsActivity : BaseActivity() {
|
||||
}
|
||||
true
|
||||
}
|
||||
autoUpdateInterval?.setOnPreferenceChangeListener { _, any ->
|
||||
var nval = any as String
|
||||
// autoUpdateInterval?.setOnPreferenceChangeListener { _, any ->
|
||||
// var nval = any as String
|
||||
//
|
||||
// // It must be greater than 15 minutes because WorkManager couldn't run tasks under 15 minutes intervals
|
||||
// nval =
|
||||
// if (TextUtils.isEmpty(nval) || nval.toLongEx() < 15) AppConfig.SUBSCRIPTION_DEFAULT_UPDATE_INTERVAL else nval
|
||||
// autoUpdateInterval?.summary = nval
|
||||
// configureUpdateTask(nval.toLongEx())
|
||||
// true
|
||||
// }
|
||||
|
||||
// It must be greater than 15 minutes because WorkManager couldn't run tasks under 15 minutes intervals
|
||||
nval =
|
||||
if (TextUtils.isEmpty(nval) || nval.toLongEx() < 15) AppConfig.SUBSCRIPTION_DEFAULT_UPDATE_INTERVAL else nval
|
||||
autoUpdateInterval?.summary = nval
|
||||
configureUpdateTask(nval.toLongEx())
|
||||
true
|
||||
}
|
||||
|
||||
socksPort?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
socksPort?.summary = nval.ifEmpty { AppConfig.PORT_SOCKS }
|
||||
true
|
||||
}
|
||||
|
||||
remoteDns?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
remoteDns?.summary = nval.ifEmpty { AppConfig.DNS_PROXY }
|
||||
true
|
||||
}
|
||||
domesticDns?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
domesticDns?.summary = nval.ifEmpty { AppConfig.DNS_DIRECT }
|
||||
true
|
||||
}
|
||||
dnsHosts?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
dnsHosts?.summary = nval
|
||||
true
|
||||
}
|
||||
delayTestUrl?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
delayTestUrl?.summary = nval.ifEmpty { AppConfig.DELAY_TEST_URL }
|
||||
true
|
||||
}
|
||||
ipApiUrl?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
ipApiUrl?.summary = nval.ifEmpty { AppConfig.IP_API_URL }
|
||||
true
|
||||
}
|
||||
// socksPort?.setOnPreferenceChangeListener { _, any ->
|
||||
// val nval = any as String
|
||||
// socksPort?.summary = nval.ifEmpty { AppConfig.PORT_SOCKS }
|
||||
// true
|
||||
// }
|
||||
//
|
||||
// remoteDns?.setOnPreferenceChangeListener { _, any ->
|
||||
// val nval = any as String
|
||||
// remoteDns?.summary = nval.ifEmpty { AppConfig.DNS_PROXY }
|
||||
// true
|
||||
// }
|
||||
// domesticDns?.setOnPreferenceChangeListener { _, any ->
|
||||
// val nval = any as String
|
||||
// domesticDns?.summary = nval.ifEmpty { AppConfig.DNS_DIRECT }
|
||||
// true
|
||||
// }
|
||||
// dnsHosts?.setOnPreferenceChangeListener { _, any ->
|
||||
// val nval = any as String
|
||||
// dnsHosts?.summary = nval
|
||||
// true
|
||||
// }
|
||||
// delayTestUrl?.setOnPreferenceChangeListener { _, any ->
|
||||
// val nval = any as String
|
||||
// delayTestUrl?.summary = nval.ifEmpty { AppConfig.DELAY_TEST_URL }
|
||||
// true
|
||||
// }
|
||||
// ipApiUrl?.setOnPreferenceChangeListener { _, any ->
|
||||
// val nval = any as String
|
||||
// ipApiUrl?.summary = nval.ifEmpty { AppConfig.IP_API_URL }
|
||||
// true
|
||||
// }
|
||||
mode?.setOnPreferenceChangeListener { _, newValue ->
|
||||
updateMode(newValue.toString())
|
||||
true
|
||||
@@ -191,113 +196,151 @@ class SettingsActivity : BaseActivity() {
|
||||
// true
|
||||
// }
|
||||
|
||||
hevTunRwTimeout?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
hevTunRwTimeout?.summary = nval.ifEmpty { AppConfig.HEVTUN_RW_TIMEOUT }
|
||||
true
|
||||
// hevTunRwTimeout?.setOnPreferenceChangeListener { _, any ->
|
||||
// val nval = any as String
|
||||
// hevTunRwTimeout?.summary = nval.ifEmpty { AppConfig.HEVTUN_RW_TIMEOUT }
|
||||
// true
|
||||
// }
|
||||
}
|
||||
|
||||
private fun initPreferenceSummaries() {
|
||||
fun updateSummary(pref: androidx.preference.Preference) {
|
||||
when (pref) {
|
||||
is EditTextPreference -> {
|
||||
pref.summary = pref.text.orEmpty()
|
||||
pref.setOnPreferenceChangeListener { p, newValue ->
|
||||
p.summary = (newValue as? String).orEmpty()
|
||||
true
|
||||
}
|
||||
}
|
||||
is ListPreference -> {
|
||||
pref.summary = pref.entry ?: ""
|
||||
pref.setOnPreferenceChangeListener { p, newValue ->
|
||||
val lp = p as ListPreference
|
||||
val idx = lp.findIndexOfValue(newValue as? String)
|
||||
lp.summary = (if (idx >= 0) lp.entries[idx] else newValue) as CharSequence?
|
||||
true
|
||||
}
|
||||
}
|
||||
is CheckBoxPreference, is androidx.preference.SwitchPreferenceCompat -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun traverse(group: androidx.preference.PreferenceGroup) {
|
||||
for (i in 0 until group.preferenceCount) {
|
||||
val p = group.getPreference(i)
|
||||
when (p) {
|
||||
is androidx.preference.PreferenceGroup -> traverse(p)
|
||||
else -> updateSummary(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preferenceScreen?.let { traverse(it) }
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
// Initialize mode-dependent UI states
|
||||
updateMode(MmkvManager.decodeSettingsString(AppConfig.PREF_MODE, VPN))
|
||||
localDns?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_LOCAL_DNS_ENABLED, false)
|
||||
fakeDns?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_FAKE_DNS_ENABLED, false)
|
||||
appendHttpProxy?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_APPEND_HTTP_PROXY, false)
|
||||
// localDnsPort?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_LOCAL_DNS_PORT, AppConfig.PORT_LOCAL_DNS)
|
||||
vpnDns?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_DNS, AppConfig.DNS_VPN)
|
||||
vpnMtu?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_MTU, AppConfig.VPN_MTU.toString())
|
||||
|
||||
// Initialize mux-dependent UI states
|
||||
updateMux(MmkvManager.decodeSettingsBool(AppConfig.PREF_MUX_ENABLED, false))
|
||||
mux?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_MUX_ENABLED, false)
|
||||
muxConcurrency?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_MUX_CONCURRENCY, "8")
|
||||
muxXudpConcurrency?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_MUX_XUDP_CONCURRENCY, "8")
|
||||
|
||||
// Initialize fragment-dependent UI states
|
||||
updateFragment(MmkvManager.decodeSettingsBool(AppConfig.PREF_FRAGMENT_ENABLED, false))
|
||||
fragment?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_FRAGMENT_ENABLED, false)
|
||||
fragmentPackets?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_PACKETS, "tlshello")
|
||||
fragmentLength?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_LENGTH, "50-100")
|
||||
fragmentInterval?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_INTERVAL, "10-20")
|
||||
|
||||
autoUpdateCheck?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.SUBSCRIPTION_AUTO_UPDATE, false)
|
||||
autoUpdateInterval?.summary =
|
||||
MmkvManager.decodeSettingsString(AppConfig.SUBSCRIPTION_AUTO_UPDATE_INTERVAL, AppConfig.SUBSCRIPTION_DEFAULT_UPDATE_INTERVAL)
|
||||
// Initialize auto-update interval state
|
||||
autoUpdateInterval?.isEnabled = MmkvManager.decodeSettingsBool(AppConfig.SUBSCRIPTION_AUTO_UPDATE, false)
|
||||
|
||||
socksPort?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_SOCKS_PORT, AppConfig.PORT_SOCKS)
|
||||
remoteDns?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_REMOTE_DNS, AppConfig.DNS_PROXY)
|
||||
domesticDns?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_DOMESTIC_DNS, AppConfig.DNS_DIRECT)
|
||||
dnsHosts?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_DNS_HOSTS)
|
||||
delayTestUrl?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_DELAY_TEST_URL, AppConfig.DELAY_TEST_URL)
|
||||
ipApiUrl?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_IP_API_URL, AppConfig.IP_API_URL)
|
||||
// localDns?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_LOCAL_DNS_ENABLED, false)
|
||||
// fakeDns?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_FAKE_DNS_ENABLED, false)
|
||||
// appendHttpProxy?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_APPEND_HTTP_PROXY, false)
|
||||
// vpnDns?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_DNS, AppConfig.DNS_VPN)
|
||||
// vpnMtu?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_MTU, AppConfig.VPN_MTU.toString())
|
||||
// mux?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_MUX_ENABLED, false)
|
||||
// muxConcurrency?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_MUX_CONCURRENCY, "8")
|
||||
// muxXudpConcurrency?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_MUX_XUDP_CONCURRENCY, "8")
|
||||
// fragment?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_FRAGMENT_ENABLED, false)
|
||||
// fragmentPackets?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_PACKETS, "tlshello")
|
||||
// fragmentLength?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_LENGTH, "50-100")
|
||||
// fragmentInterval?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_INTERVAL, "10-20")
|
||||
// autoUpdateCheck?.isChecked = MmkvManager.decodeSettingsBool(AppConfig.SUBSCRIPTION_AUTO_UPDATE, false)
|
||||
// autoUpdateInterval?.summary =
|
||||
// MmkvManager.decodeSettingsString(AppConfig.SUBSCRIPTION_AUTO_UPDATE_INTERVAL, AppConfig.SUBSCRIPTION_DEFAULT_UPDATE_INTERVAL)
|
||||
// socksPort?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_SOCKS_PORT, AppConfig.PORT_SOCKS)
|
||||
// remoteDns?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_REMOTE_DNS, AppConfig.DNS_PROXY)
|
||||
// domesticDns?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_DOMESTIC_DNS, AppConfig.DNS_DIRECT)
|
||||
// dnsHosts?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_DNS_HOSTS)
|
||||
// delayTestUrl?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_DELAY_TEST_URL, AppConfig.DELAY_TEST_URL)
|
||||
// ipApiUrl?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_IP_API_URL, AppConfig.IP_API_URL)
|
||||
// hevTunRwTimeout?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT, AppConfig.HEVTUN_RW_TIMEOUT)
|
||||
|
||||
//updateHevTunSettings(MmkvManager.decodeSettingsBool(AppConfig.PREF_USE_HEV_TUNNEL, true))
|
||||
hevTunRwTimeout?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT, AppConfig.HEVTUN_RW_TIMEOUT)
|
||||
|
||||
initSharedPreference()
|
||||
// initSharedPreference()
|
||||
}
|
||||
|
||||
private fun initSharedPreference() {
|
||||
listOf(
|
||||
//localDnsPort,
|
||||
vpnDns,
|
||||
vpnMtu,
|
||||
muxConcurrency,
|
||||
muxXudpConcurrency,
|
||||
fragmentLength,
|
||||
fragmentInterval,
|
||||
autoUpdateInterval,
|
||||
socksPort,
|
||||
remoteDns,
|
||||
domesticDns,
|
||||
delayTestUrl,
|
||||
ipApiUrl,
|
||||
hevTunRwTimeout
|
||||
).forEach { key ->
|
||||
key?.text = key.summary.toString()
|
||||
}
|
||||
// listOf(
|
||||
// //localDnsPort,
|
||||
// vpnDns,
|
||||
// vpnMtu,
|
||||
// muxConcurrency,
|
||||
// muxXudpConcurrency,
|
||||
// fragmentLength,
|
||||
// fragmentInterval,
|
||||
// autoUpdateInterval,
|
||||
// socksPort,
|
||||
// remoteDns,
|
||||
// domesticDns,
|
||||
// delayTestUrl,
|
||||
// ipApiUrl,
|
||||
// hevTunRwTimeout
|
||||
// ).forEach { key ->
|
||||
// key?.summary = key.text.toString()
|
||||
// }
|
||||
|
||||
listOf(
|
||||
AppConfig.PREF_SNIFFING_ENABLED,
|
||||
AppConfig.PREF_USE_HEV_TUNNEL
|
||||
).forEach { key ->
|
||||
findPreference<CheckBoxPreference>(key)?.isChecked =
|
||||
MmkvManager.decodeSettingsBool(key, true)
|
||||
}
|
||||
|
||||
listOf(
|
||||
AppConfig.PREF_ROUTE_ONLY_ENABLED,
|
||||
AppConfig.PREF_IS_BOOTED,
|
||||
AppConfig.PREF_BYPASS_APPS,
|
||||
AppConfig.PREF_SPEED_ENABLED,
|
||||
AppConfig.PREF_CONFIRM_REMOVE,
|
||||
AppConfig.PREF_START_SCAN_IMMEDIATE,
|
||||
AppConfig.PREF_DOUBLE_COLUMN_DISPLAY,
|
||||
AppConfig.PREF_PREFER_IPV6,
|
||||
AppConfig.PREF_PROXY_SHARING,
|
||||
AppConfig.PREF_ALLOW_INSECURE
|
||||
).forEach { key ->
|
||||
findPreference<CheckBoxPreference>(key)?.isChecked =
|
||||
MmkvManager.decodeSettingsBool(key, false)
|
||||
}
|
||||
|
||||
listOf(
|
||||
AppConfig.PREF_VPN_BYPASS_LAN,
|
||||
AppConfig.PREF_VPN_INTERFACE_ADDRESS_CONFIG_INDEX,
|
||||
AppConfig.PREF_ROUTING_DOMAIN_STRATEGY,
|
||||
AppConfig.PREF_MUX_XUDP_QUIC,
|
||||
AppConfig.PREF_FRAGMENT_PACKETS,
|
||||
AppConfig.PREF_LANGUAGE,
|
||||
AppConfig.PREF_UI_MODE_NIGHT,
|
||||
AppConfig.PREF_LOGLEVEL,
|
||||
AppConfig.PREF_OUTBOUND_DOMAIN_RESOLVE_METHOD,
|
||||
AppConfig.PREF_MODE,
|
||||
AppConfig.PREF_HEV_TUNNEL_LOGLEVEL
|
||||
).forEach { key ->
|
||||
if (MmkvManager.decodeSettingsString(key) != null) {
|
||||
findPreference<ListPreference>(key)?.value = MmkvManager.decodeSettingsString(key)
|
||||
}
|
||||
}
|
||||
// listOf(
|
||||
// AppConfig.PREF_SNIFFING_ENABLED,
|
||||
// AppConfig.PREF_USE_HEV_TUNNEL
|
||||
// ).forEach { key ->
|
||||
// findPreference<CheckBoxPreference>(key)?.isChecked =
|
||||
// MmkvManager.decodeSettingsBool(key, true)
|
||||
// }
|
||||
//
|
||||
// listOf(
|
||||
// AppConfig.PREF_ROUTE_ONLY_ENABLED,
|
||||
// AppConfig.PREF_IS_BOOTED,
|
||||
// AppConfig.PREF_BYPASS_APPS,
|
||||
// AppConfig.PREF_SPEED_ENABLED,
|
||||
// AppConfig.PREF_CONFIRM_REMOVE,
|
||||
// AppConfig.PREF_START_SCAN_IMMEDIATE,
|
||||
// AppConfig.PREF_DOUBLE_COLUMN_DISPLAY,
|
||||
// AppConfig.PREF_PREFER_IPV6,
|
||||
// AppConfig.PREF_PROXY_SHARING,
|
||||
// AppConfig.PREF_ALLOW_INSECURE
|
||||
// ).forEach { key ->
|
||||
// findPreference<CheckBoxPreference>(key)?.isChecked =
|
||||
// MmkvManager.decodeSettingsBool(key, false)
|
||||
// }
|
||||
//
|
||||
// listOf(
|
||||
// AppConfig.PREF_VPN_BYPASS_LAN,
|
||||
// AppConfig.PREF_VPN_INTERFACE_ADDRESS_CONFIG_INDEX,
|
||||
// AppConfig.PREF_ROUTING_DOMAIN_STRATEGY,
|
||||
// AppConfig.PREF_MUX_XUDP_QUIC,
|
||||
// AppConfig.PREF_FRAGMENT_PACKETS,
|
||||
// AppConfig.PREF_LANGUAGE,
|
||||
// AppConfig.PREF_UI_MODE_NIGHT,
|
||||
// AppConfig.PREF_LOGLEVEL,
|
||||
// AppConfig.PREF_OUTBOUND_DOMAIN_RESOLVE_METHOD,
|
||||
// AppConfig.PREF_MODE,
|
||||
// AppConfig.PREF_HEV_TUNNEL_LOGLEVEL
|
||||
// ).forEach { key ->
|
||||
// if (MmkvManager.decodeSettingsString(key) != null) {
|
||||
// findPreference<ListPreference>(key)?.value = MmkvManager.decodeSettingsString(key)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private fun updateMode(mode: String?) {
|
||||
@@ -381,29 +424,29 @@ class SettingsActivity : BaseActivity() {
|
||||
fragmentPackets?.isEnabled = enabled
|
||||
fragmentLength?.isEnabled = enabled
|
||||
fragmentInterval?.isEnabled = enabled
|
||||
if (enabled) {
|
||||
updateFragmentPackets(MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_PACKETS, "tlshello"))
|
||||
updateFragmentLength(MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_LENGTH, "50-100"))
|
||||
updateFragmentInterval(MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_INTERVAL, "10-20"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateFragmentPackets(value: String?) {
|
||||
fragmentPackets?.summary = value.toString()
|
||||
}
|
||||
|
||||
private fun updateFragmentLength(value: String?) {
|
||||
fragmentLength?.summary = value.toString()
|
||||
}
|
||||
|
||||
private fun updateFragmentInterval(value: String?) {
|
||||
fragmentInterval?.summary = value.toString()
|
||||
}
|
||||
|
||||
private fun updateHevTunSettings(enabled: Boolean) {
|
||||
hevTunLogLevel?.isEnabled = enabled
|
||||
hevTunRwTimeout?.isEnabled = enabled
|
||||
// if (enabled) {
|
||||
// updateFragmentPackets(MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_PACKETS, "tlshello"))
|
||||
// updateFragmentLength(MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_LENGTH, "50-100"))
|
||||
// updateFragmentInterval(MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_INTERVAL, "10-20"))
|
||||
// }
|
||||
}
|
||||
//
|
||||
// private fun updateFragmentPackets(value: String?) {
|
||||
// fragmentPackets?.summary = value.toString()
|
||||
// }
|
||||
//
|
||||
// private fun updateFragmentLength(value: String?) {
|
||||
// fragmentLength?.summary = value.toString()
|
||||
// }
|
||||
//
|
||||
// private fun updateFragmentInterval(value: String?) {
|
||||
// fragmentInterval?.summary = value.toString()
|
||||
// }
|
||||
//
|
||||
// private fun updateHevTunSettings(enabled: Boolean) {
|
||||
// hevTunLogLevel?.isEnabled = enabled
|
||||
// hevTunRwTimeout?.isEnabled = enabled
|
||||
// }
|
||||
}
|
||||
|
||||
fun onModeHelpClicked(view: View) {
|
||||
|
||||
@@ -237,9 +237,11 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
val serversCopy = serversCache.toList()
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
for (item in serversCopy) {
|
||||
MessageUtil.sendMsg2TestService(getApplication(), AppConfig.MSG_MEASURE_CONFIG, item.guid)
|
||||
val guids = ArrayList<String>(serversCopy.map { it.guid })
|
||||
if (guids.isEmpty()) {
|
||||
return@launch
|
||||
}
|
||||
MessageUtil.sendMsg2TestService(getApplication(), AppConfig.MSG_MEASURE_CONFIG, guids)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user