pumaguard 21.post27__py3-none-any.whl → 21.post83__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pumaguard/presets.py +1 -0
- pumaguard/pumaguard-ui/.last_build_id +1 -1
- pumaguard/pumaguard-ui/assets/NOTICES +621 -71
- pumaguard/pumaguard-ui/assets/fonts/MaterialIcons-Regular.otf +0 -0
- pumaguard/pumaguard-ui/flutter_bootstrap.js +1 -1
- pumaguard/pumaguard-ui/main.dart.js +28869 -28787
- pumaguard/web_routes/dhcp.py +311 -54
- pumaguard/web_routes/diagnostics.py +6 -0
- pumaguard/web_routes/settings.py +13 -0
- pumaguard/web_ui.py +29 -0
- {pumaguard-21.post27.dist-info → pumaguard-21.post83.dist-info}/METADATA +1 -1
- pumaguard-21.post83.dist-info/RECORD +254 -0
- pumaguard-ui/.gitignore +48 -0
- pumaguard-ui/.metadata +45 -0
- pumaguard-ui/API_REFERENCE.md +717 -0
- pumaguard-ui/LICENSE +201 -0
- pumaguard-ui/Makefile +36 -0
- pumaguard-ui/README.md +371 -0
- pumaguard-ui/UI_DEVELOPMENT_CONTEXT.md +427 -0
- pumaguard-ui/analysis_options.yaml +28 -0
- pumaguard-ui/android/.gitignore +14 -0
- pumaguard-ui/android/app/build.gradle.kts +44 -0
- pumaguard-ui/android/app/src/debug/AndroidManifest.xml +7 -0
- pumaguard-ui/android/app/src/main/AndroidManifest.xml +45 -0
- pumaguard-ui/android/app/src/main/kotlin/com/example/pumaguard_ui/MainActivity.kt +5 -0
- pumaguard-ui/android/app/src/main/res/drawable/launch_background.xml +12 -0
- pumaguard-ui/android/app/src/main/res/drawable-v21/launch_background.xml +12 -0
- pumaguard-ui/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- pumaguard-ui/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- pumaguard-ui/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- pumaguard-ui/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- pumaguard-ui/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- pumaguard-ui/android/app/src/main/res/values/styles.xml +18 -0
- pumaguard-ui/android/app/src/main/res/values-night/styles.xml +18 -0
- pumaguard-ui/android/app/src/profile/AndroidManifest.xml +7 -0
- pumaguard-ui/android/build.gradle.kts +24 -0
- pumaguard-ui/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- pumaguard-ui/android/gradle.properties +2 -0
- pumaguard-ui/android/settings.gradle.kts +26 -0
- pumaguard-ui/fonts/README.md +38 -0
- pumaguard-ui/fonts/Roboto-Bold.ttf +0 -0
- pumaguard-ui/fonts/Roboto-Light.ttf +0 -0
- pumaguard-ui/fonts/Roboto-Medium.ttf +0 -0
- pumaguard-ui/fonts/Roboto-Regular.ttf +0 -0
- pumaguard-ui/fonts/RobotoMono-Bold.ttf +0 -0
- pumaguard-ui/fonts/RobotoMono-Medium.ttf +0 -0
- pumaguard-ui/fonts/RobotoMono-Regular.ttf +0 -0
- pumaguard-ui/fonts/download_fonts.sh +76 -0
- pumaguard-ui/ios/.gitignore +34 -0
- pumaguard-ui/ios/Flutter/AppFrameworkInfo.plist +26 -0
- pumaguard-ui/ios/Flutter/Debug.xcconfig +1 -0
- pumaguard-ui/ios/Flutter/Release.xcconfig +1 -0
- pumaguard-ui/ios/Runner/AppDelegate.swift +13 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +122 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +23 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +0 -0
- pumaguard-ui/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +5 -0
- pumaguard-ui/ios/Runner/Base.lproj/LaunchScreen.storyboard +37 -0
- pumaguard-ui/ios/Runner/Base.lproj/Main.storyboard +26 -0
- pumaguard-ui/ios/Runner/Info.plist +49 -0
- pumaguard-ui/ios/Runner/Runner-Bridging-Header.h +1 -0
- pumaguard-ui/ios/Runner.xcodeproj/project.pbxproj +616 -0
- pumaguard-ui/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- pumaguard-ui/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- pumaguard-ui/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
- pumaguard-ui/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +101 -0
- pumaguard-ui/ios/Runner.xcworkspace/contents.xcworkspacedata +7 -0
- pumaguard-ui/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- pumaguard-ui/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
- pumaguard-ui/ios/RunnerTests/RunnerTests.swift +12 -0
- pumaguard-ui/lib/main.dart +56 -0
- pumaguard-ui/lib/models/camera.dart +45 -0
- pumaguard-ui/lib/models/plug.dart +45 -0
- pumaguard-ui/lib/models/settings.dart +112 -0
- pumaguard-ui/lib/models/status.dart +58 -0
- pumaguard-ui/lib/screens/directories_screen.dart +319 -0
- pumaguard-ui/lib/screens/home_screen.dart +545 -0
- pumaguard-ui/lib/screens/image_browser_screen.dart +1248 -0
- pumaguard-ui/lib/screens/server_discovery_screen.dart +390 -0
- pumaguard-ui/lib/screens/settings_screen.dart +1162 -0
- pumaguard-ui/lib/screens/wifi_settings_screen.dart +671 -0
- pumaguard-ui/lib/services/api_service.dart +717 -0
- pumaguard-ui/lib/services/camera_events_service.dart +195 -0
- pumaguard-ui/lib/services/mdns_service.dart +4 -0
- pumaguard-ui/lib/services/mdns_service_impl.dart +282 -0
- pumaguard-ui/lib/services/mdns_service_io.dart +1 -0
- pumaguard-ui/lib/services/mdns_service_web.dart +106 -0
- pumaguard-ui/lib/utils/download_helper.dart +2 -0
- pumaguard-ui/lib/utils/download_helper_stub.dart +6 -0
- pumaguard-ui/lib/utils/download_helper_web.dart +14 -0
- pumaguard-ui/lib/utils/platform_url.dart +10 -0
- pumaguard-ui/lib/utils/platform_url_stub.dart +11 -0
- pumaguard-ui/lib/utils/platform_url_web.dart +16 -0
- pumaguard-ui/linux/.gitignore +1 -0
- pumaguard-ui/linux/CMakeLists.txt +128 -0
- pumaguard-ui/linux/flutter/CMakeLists.txt +88 -0
- pumaguard-ui/linux/flutter/generated_plugin_registrant.cc +15 -0
- pumaguard-ui/linux/flutter/generated_plugin_registrant.h +15 -0
- pumaguard-ui/linux/flutter/generated_plugins.cmake +24 -0
- pumaguard-ui/linux/runner/CMakeLists.txt +26 -0
- pumaguard-ui/linux/runner/main.cc +6 -0
- pumaguard-ui/linux/runner/my_application.cc +148 -0
- pumaguard-ui/linux/runner/my_application.h +21 -0
- pumaguard-ui/macos/.gitignore +7 -0
- pumaguard-ui/macos/Flutter/Flutter-Debug.xcconfig +1 -0
- pumaguard-ui/macos/Flutter/Flutter-Release.xcconfig +1 -0
- pumaguard-ui/macos/Flutter/GeneratedPluginRegistrant.swift +16 -0
- pumaguard-ui/macos/Runner/AppDelegate.swift +13 -0
- pumaguard-ui/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
- pumaguard-ui/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
- pumaguard-ui/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
- pumaguard-ui/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
- pumaguard-ui/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
- pumaguard-ui/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
- pumaguard-ui/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
- pumaguard-ui/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
- pumaguard-ui/macos/Runner/Base.lproj/MainMenu.xib +343 -0
- pumaguard-ui/macos/Runner/Configs/AppInfo.xcconfig +14 -0
- pumaguard-ui/macos/Runner/Configs/Debug.xcconfig +2 -0
- pumaguard-ui/macos/Runner/Configs/Release.xcconfig +2 -0
- pumaguard-ui/macos/Runner/Configs/Warnings.xcconfig +13 -0
- pumaguard-ui/macos/Runner/DebugProfile.entitlements +12 -0
- pumaguard-ui/macos/Runner/Info.plist +32 -0
- pumaguard-ui/macos/Runner/MainFlutterWindow.swift +15 -0
- pumaguard-ui/macos/Runner/Release.entitlements +8 -0
- pumaguard-ui/macos/Runner.xcodeproj/project.pbxproj +705 -0
- pumaguard-ui/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- pumaguard-ui/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +99 -0
- pumaguard-ui/macos/Runner.xcworkspace/contents.xcworkspacedata +7 -0
- pumaguard-ui/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- pumaguard-ui/macos/RunnerTests/RunnerTests.swift +12 -0
- pumaguard-ui/pubspec.lock +882 -0
- pumaguard-ui/pubspec.yaml +125 -0
- pumaguard-ui/test/models/camera_test.dart +515 -0
- pumaguard-ui/test/models/plug_test.dart +499 -0
- pumaguard-ui/test/models/settings_test.dart +903 -0
- pumaguard-ui/test/models/status_test.dart +707 -0
- pumaguard-ui/test/screens/image_browser_grouping_test.dart +555 -0
- pumaguard-ui/test/services/api_service_cameras_test.dart +580 -0
- pumaguard-ui/test/services/api_service_image_browser_test.dart +512 -0
- pumaguard-ui/test/widget_test.dart.skip +38 -0
- pumaguard-ui/web/favicon.png +0 -0
- pumaguard-ui/web/icons/Icon-192.png +0 -0
- pumaguard-ui/web/icons/Icon-512.png +0 -0
- pumaguard-ui/web/icons/Icon-maskable-192.png +0 -0
- pumaguard-ui/web/icons/Icon-maskable-512.png +0 -0
- pumaguard-ui/web/index.html +38 -0
- pumaguard-ui/web/manifest.json +35 -0
- pumaguard-ui/windows/.gitignore +17 -0
- pumaguard-ui/windows/CMakeLists.txt +108 -0
- pumaguard-ui/windows/flutter/CMakeLists.txt +109 -0
- pumaguard-ui/windows/flutter/generated_plugin_registrant.cc +14 -0
- pumaguard-ui/windows/flutter/generated_plugin_registrant.h +15 -0
- pumaguard-ui/windows/flutter/generated_plugins.cmake +24 -0
- pumaguard-ui/windows/runner/CMakeLists.txt +40 -0
- pumaguard-ui/windows/runner/Runner.rc +121 -0
- pumaguard-ui/windows/runner/flutter_window.cpp +71 -0
- pumaguard-ui/windows/runner/flutter_window.h +33 -0
- pumaguard-ui/windows/runner/main.cpp +43 -0
- pumaguard-ui/windows/runner/resource.h +16 -0
- pumaguard-ui/windows/runner/resources/app_icon.ico +0 -0
- pumaguard-ui/windows/runner/runner.exe.manifest +14 -0
- pumaguard-ui/windows/runner/utils.cpp +65 -0
- pumaguard-ui/windows/runner/utils.h +19 -0
- pumaguard-ui/windows/runner/win32_window.cpp +288 -0
- pumaguard-ui/windows/runner/win32_window.h +102 -0
- pumaguard-21.post27.dist-info/RECORD +0 -83
- {pumaguard-21.post27.dist-info → pumaguard-21.post83.dist-info}/WHEEL +0 -0
- {pumaguard-21.post27.dist-info → pumaguard-21.post83.dist-info}/entry_points.txt +0 -0
- {pumaguard-21.post27.dist-info → pumaguard-21.post83.dist-info}/licenses/LICENSE +0 -0
- {pumaguard-21.post27.dist-info → pumaguard-21.post83.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<Scheme
|
|
3
|
+
LastUpgradeVersion = "1510"
|
|
4
|
+
version = "1.3">
|
|
5
|
+
<BuildAction
|
|
6
|
+
parallelizeBuildables = "YES"
|
|
7
|
+
buildImplicitDependencies = "YES">
|
|
8
|
+
<BuildActionEntries>
|
|
9
|
+
<BuildActionEntry
|
|
10
|
+
buildForTesting = "YES"
|
|
11
|
+
buildForRunning = "YES"
|
|
12
|
+
buildForProfiling = "YES"
|
|
13
|
+
buildForArchiving = "YES"
|
|
14
|
+
buildForAnalyzing = "YES">
|
|
15
|
+
<BuildableReference
|
|
16
|
+
BuildableIdentifier = "primary"
|
|
17
|
+
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
|
18
|
+
BuildableName = "Runner.app"
|
|
19
|
+
BlueprintName = "Runner"
|
|
20
|
+
ReferencedContainer = "container:Runner.xcodeproj">
|
|
21
|
+
</BuildableReference>
|
|
22
|
+
</BuildActionEntry>
|
|
23
|
+
</BuildActionEntries>
|
|
24
|
+
</BuildAction>
|
|
25
|
+
<TestAction
|
|
26
|
+
buildConfiguration = "Debug"
|
|
27
|
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
28
|
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
29
|
+
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
|
30
|
+
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
31
|
+
<MacroExpansion>
|
|
32
|
+
<BuildableReference
|
|
33
|
+
BuildableIdentifier = "primary"
|
|
34
|
+
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
|
35
|
+
BuildableName = "Runner.app"
|
|
36
|
+
BlueprintName = "Runner"
|
|
37
|
+
ReferencedContainer = "container:Runner.xcodeproj">
|
|
38
|
+
</BuildableReference>
|
|
39
|
+
</MacroExpansion>
|
|
40
|
+
<Testables>
|
|
41
|
+
<TestableReference
|
|
42
|
+
skipped = "NO"
|
|
43
|
+
parallelizable = "YES">
|
|
44
|
+
<BuildableReference
|
|
45
|
+
BuildableIdentifier = "primary"
|
|
46
|
+
BlueprintIdentifier = "331C8080294A63A400263BE5"
|
|
47
|
+
BuildableName = "RunnerTests.xctest"
|
|
48
|
+
BlueprintName = "RunnerTests"
|
|
49
|
+
ReferencedContainer = "container:Runner.xcodeproj">
|
|
50
|
+
</BuildableReference>
|
|
51
|
+
</TestableReference>
|
|
52
|
+
</Testables>
|
|
53
|
+
</TestAction>
|
|
54
|
+
<LaunchAction
|
|
55
|
+
buildConfiguration = "Debug"
|
|
56
|
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
57
|
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
58
|
+
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
|
59
|
+
launchStyle = "0"
|
|
60
|
+
useCustomWorkingDirectory = "NO"
|
|
61
|
+
ignoresPersistentStateOnLaunch = "NO"
|
|
62
|
+
debugDocumentVersioning = "YES"
|
|
63
|
+
debugServiceExtension = "internal"
|
|
64
|
+
enableGPUValidationMode = "1"
|
|
65
|
+
allowLocationSimulation = "YES">
|
|
66
|
+
<BuildableProductRunnable
|
|
67
|
+
runnableDebuggingMode = "0">
|
|
68
|
+
<BuildableReference
|
|
69
|
+
BuildableIdentifier = "primary"
|
|
70
|
+
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
|
71
|
+
BuildableName = "Runner.app"
|
|
72
|
+
BlueprintName = "Runner"
|
|
73
|
+
ReferencedContainer = "container:Runner.xcodeproj">
|
|
74
|
+
</BuildableReference>
|
|
75
|
+
</BuildableProductRunnable>
|
|
76
|
+
</LaunchAction>
|
|
77
|
+
<ProfileAction
|
|
78
|
+
buildConfiguration = "Profile"
|
|
79
|
+
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
80
|
+
savedToolIdentifier = ""
|
|
81
|
+
useCustomWorkingDirectory = "NO"
|
|
82
|
+
debugDocumentVersioning = "YES">
|
|
83
|
+
<BuildableProductRunnable
|
|
84
|
+
runnableDebuggingMode = "0">
|
|
85
|
+
<BuildableReference
|
|
86
|
+
BuildableIdentifier = "primary"
|
|
87
|
+
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
|
88
|
+
BuildableName = "Runner.app"
|
|
89
|
+
BlueprintName = "Runner"
|
|
90
|
+
ReferencedContainer = "container:Runner.xcodeproj">
|
|
91
|
+
</BuildableReference>
|
|
92
|
+
</BuildableProductRunnable>
|
|
93
|
+
</ProfileAction>
|
|
94
|
+
<AnalyzeAction
|
|
95
|
+
buildConfiguration = "Debug">
|
|
96
|
+
</AnalyzeAction>
|
|
97
|
+
<ArchiveAction
|
|
98
|
+
buildConfiguration = "Release"
|
|
99
|
+
revealArchiveInOrganizer = "YES">
|
|
100
|
+
</ArchiveAction>
|
|
101
|
+
</Scheme>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Flutter
|
|
2
|
+
import UIKit
|
|
3
|
+
import XCTest
|
|
4
|
+
|
|
5
|
+
class RunnerTests: XCTestCase {
|
|
6
|
+
|
|
7
|
+
func testExample() {
|
|
8
|
+
// If you add code to the Runner application, consider adding tests here.
|
|
9
|
+
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
import 'package:provider/provider.dart';
|
|
3
|
+
import 'screens/home_screen.dart';
|
|
4
|
+
import 'services/api_service.dart';
|
|
5
|
+
import 'version.dart';
|
|
6
|
+
|
|
7
|
+
void main() {
|
|
8
|
+
runApp(const PumaGuardApp());
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class PumaGuardApp extends StatelessWidget {
|
|
12
|
+
const PumaGuardApp({super.key});
|
|
13
|
+
|
|
14
|
+
@override
|
|
15
|
+
Widget build(BuildContext context) {
|
|
16
|
+
return Provider<ApiService>(
|
|
17
|
+
create: (_) => ApiService(),
|
|
18
|
+
child: MaterialApp(
|
|
19
|
+
title: 'PumaGuard $appVersion',
|
|
20
|
+
debugShowCheckedModeBanner: false,
|
|
21
|
+
theme: ThemeData(
|
|
22
|
+
useMaterial3: true,
|
|
23
|
+
fontFamily: 'Roboto',
|
|
24
|
+
colorScheme: ColorScheme.fromSeed(
|
|
25
|
+
seedColor: const Color(0xFF8B4513), // Brown/puma color
|
|
26
|
+
brightness: Brightness.light,
|
|
27
|
+
),
|
|
28
|
+
cardTheme: CardThemeData(
|
|
29
|
+
elevation: 2,
|
|
30
|
+
shape: RoundedRectangleBorder(
|
|
31
|
+
borderRadius: BorderRadius.circular(12),
|
|
32
|
+
),
|
|
33
|
+
),
|
|
34
|
+
appBarTheme: const AppBarTheme(centerTitle: true, elevation: 0),
|
|
35
|
+
),
|
|
36
|
+
darkTheme: ThemeData(
|
|
37
|
+
useMaterial3: true,
|
|
38
|
+
fontFamily: 'Roboto',
|
|
39
|
+
colorScheme: ColorScheme.fromSeed(
|
|
40
|
+
seedColor: const Color(0xFF8B4513),
|
|
41
|
+
brightness: Brightness.dark,
|
|
42
|
+
),
|
|
43
|
+
cardTheme: CardThemeData(
|
|
44
|
+
elevation: 2,
|
|
45
|
+
shape: RoundedRectangleBorder(
|
|
46
|
+
borderRadius: BorderRadius.circular(12),
|
|
47
|
+
),
|
|
48
|
+
),
|
|
49
|
+
appBarTheme: const AppBarTheme(centerTitle: true, elevation: 0),
|
|
50
|
+
),
|
|
51
|
+
themeMode: ThemeMode.system,
|
|
52
|
+
home: const HomeScreen(),
|
|
53
|
+
),
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
class Camera {
|
|
2
|
+
final String hostname;
|
|
3
|
+
final String ipAddress;
|
|
4
|
+
final String macAddress;
|
|
5
|
+
final String lastSeen;
|
|
6
|
+
final String status;
|
|
7
|
+
|
|
8
|
+
Camera({
|
|
9
|
+
required this.hostname,
|
|
10
|
+
required this.ipAddress,
|
|
11
|
+
required this.macAddress,
|
|
12
|
+
required this.lastSeen,
|
|
13
|
+
required this.status,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
factory Camera.fromJson(Map<String, dynamic> json) {
|
|
17
|
+
return Camera(
|
|
18
|
+
hostname: json['hostname'] as String? ?? '',
|
|
19
|
+
ipAddress: json['ip_address'] as String? ?? '',
|
|
20
|
+
macAddress: json['mac_address'] as String? ?? '',
|
|
21
|
+
lastSeen: json['last_seen'] as String? ?? '',
|
|
22
|
+
status: json['status'] as String? ?? 'unknown',
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
Map<String, dynamic> toJson() {
|
|
27
|
+
return {
|
|
28
|
+
'hostname': hostname,
|
|
29
|
+
'ip_address': ipAddress,
|
|
30
|
+
'mac_address': macAddress,
|
|
31
|
+
'last_seen': lastSeen,
|
|
32
|
+
'status': status,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
bool get isConnected => status == 'connected';
|
|
37
|
+
|
|
38
|
+
String get displayName => hostname.isNotEmpty ? hostname : ipAddress;
|
|
39
|
+
|
|
40
|
+
String get cameraUrl {
|
|
41
|
+
if (ipAddress.isEmpty) return '';
|
|
42
|
+
// Return URL without scheme - let caller add http:// or https://
|
|
43
|
+
return ipAddress;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
class Plug {
|
|
2
|
+
final String hostname;
|
|
3
|
+
final String ipAddress;
|
|
4
|
+
final String macAddress;
|
|
5
|
+
final String lastSeen;
|
|
6
|
+
final String status;
|
|
7
|
+
|
|
8
|
+
Plug({
|
|
9
|
+
required this.hostname,
|
|
10
|
+
required this.ipAddress,
|
|
11
|
+
required this.macAddress,
|
|
12
|
+
required this.lastSeen,
|
|
13
|
+
required this.status,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
factory Plug.fromJson(Map<String, dynamic> json) {
|
|
17
|
+
return Plug(
|
|
18
|
+
hostname: json['hostname'] as String? ?? '',
|
|
19
|
+
ipAddress: json['ip_address'] as String? ?? '',
|
|
20
|
+
macAddress: json['mac_address'] as String? ?? '',
|
|
21
|
+
lastSeen: json['last_seen'] as String? ?? '',
|
|
22
|
+
status: json['status'] as String? ?? 'unknown',
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
Map<String, dynamic> toJson() {
|
|
27
|
+
return {
|
|
28
|
+
'hostname': hostname,
|
|
29
|
+
'ip_address': ipAddress,
|
|
30
|
+
'mac_address': macAddress,
|
|
31
|
+
'last_seen': lastSeen,
|
|
32
|
+
'status': status,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
bool get isConnected => status == 'connected';
|
|
37
|
+
|
|
38
|
+
String get displayName => hostname.isNotEmpty ? hostname : ipAddress;
|
|
39
|
+
|
|
40
|
+
String get plugUrl {
|
|
41
|
+
if (ipAddress.isEmpty) return '';
|
|
42
|
+
// Return URL without scheme - let caller add http:// or https://
|
|
43
|
+
return ipAddress;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import 'camera.dart';
|
|
2
|
+
import 'plug.dart';
|
|
3
|
+
|
|
4
|
+
class Settings {
|
|
5
|
+
final double yoloMinSize;
|
|
6
|
+
final double yoloConfThresh;
|
|
7
|
+
final int yoloMaxDets;
|
|
8
|
+
final String yoloModelFilename;
|
|
9
|
+
final String classifierModelFilename;
|
|
10
|
+
final String deterrentSoundFile;
|
|
11
|
+
final double fileStabilizationExtraWait;
|
|
12
|
+
final bool playSound;
|
|
13
|
+
final int volume;
|
|
14
|
+
final List<Camera> cameras;
|
|
15
|
+
final List<Plug> plugs;
|
|
16
|
+
|
|
17
|
+
Settings({
|
|
18
|
+
required this.yoloMinSize,
|
|
19
|
+
required this.yoloConfThresh,
|
|
20
|
+
required this.yoloMaxDets,
|
|
21
|
+
required this.yoloModelFilename,
|
|
22
|
+
required this.classifierModelFilename,
|
|
23
|
+
required this.deterrentSoundFile,
|
|
24
|
+
required this.fileStabilizationExtraWait,
|
|
25
|
+
required this.playSound,
|
|
26
|
+
required this.volume,
|
|
27
|
+
required this.cameras,
|
|
28
|
+
required this.plugs,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
factory Settings.fromJson(Map<String, dynamic> json) {
|
|
32
|
+
// Parse cameras list
|
|
33
|
+
List<Camera> camerasList = [];
|
|
34
|
+
if (json['cameras'] is List) {
|
|
35
|
+
camerasList = (json['cameras'] as List)
|
|
36
|
+
.map(
|
|
37
|
+
(cameraJson) => Camera.fromJson(cameraJson as Map<String, dynamic>),
|
|
38
|
+
)
|
|
39
|
+
.toList();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Parse plugs list
|
|
43
|
+
List<Plug> plugsList = [];
|
|
44
|
+
if (json['plugs'] is List) {
|
|
45
|
+
plugsList = (json['plugs'] as List)
|
|
46
|
+
.map((plugJson) => Plug.fromJson(plugJson as Map<String, dynamic>))
|
|
47
|
+
.toList();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return Settings(
|
|
51
|
+
yoloMinSize: (json['YOLO-min-size'] as num?)?.toDouble() ?? 0.01,
|
|
52
|
+
yoloConfThresh: (json['YOLO-conf-thresh'] as num?)?.toDouble() ?? 0.25,
|
|
53
|
+
yoloMaxDets: json['YOLO-max-dets'] as int? ?? 10,
|
|
54
|
+
yoloModelFilename: json['YOLO-model-filename'] as String? ?? '',
|
|
55
|
+
classifierModelFilename:
|
|
56
|
+
json['classifier-model-filename'] as String? ?? '',
|
|
57
|
+
deterrentSoundFile: json['deterrent-sound-file'] as String? ?? '',
|
|
58
|
+
fileStabilizationExtraWait:
|
|
59
|
+
(json['file-stabilization-extra-wait'] as num?)?.toDouble() ?? 2.0,
|
|
60
|
+
playSound: json['play-sound'] as bool? ?? false,
|
|
61
|
+
volume: json['volume'] as int? ?? 80,
|
|
62
|
+
cameras: camerasList,
|
|
63
|
+
plugs: plugsList,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
Map<String, dynamic> toJson() {
|
|
68
|
+
return {
|
|
69
|
+
'YOLO-min-size': yoloMinSize,
|
|
70
|
+
'YOLO-conf-thresh': yoloConfThresh,
|
|
71
|
+
'YOLO-max-dets': yoloMaxDets,
|
|
72
|
+
'YOLO-model-filename': yoloModelFilename,
|
|
73
|
+
'classifier-model-filename': classifierModelFilename,
|
|
74
|
+
'deterrent-sound-file': deterrentSoundFile,
|
|
75
|
+
'file-stabilization-extra-wait': fileStabilizationExtraWait,
|
|
76
|
+
'play-sound': playSound,
|
|
77
|
+
'volume': volume,
|
|
78
|
+
'cameras': cameras.map((camera) => camera.toJson()).toList(),
|
|
79
|
+
'plugs': plugs.map((plug) => plug.toJson()).toList(),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
Settings copyWith({
|
|
84
|
+
double? yoloMinSize,
|
|
85
|
+
double? yoloConfThresh,
|
|
86
|
+
int? yoloMaxDets,
|
|
87
|
+
String? yoloModelFilename,
|
|
88
|
+
String? classifierModelFilename,
|
|
89
|
+
String? deterrentSoundFile,
|
|
90
|
+
double? fileStabilizationExtraWait,
|
|
91
|
+
bool? playSound,
|
|
92
|
+
int? volume,
|
|
93
|
+
List<Camera>? cameras,
|
|
94
|
+
List<Plug>? plugs,
|
|
95
|
+
}) {
|
|
96
|
+
return Settings(
|
|
97
|
+
yoloMinSize: yoloMinSize ?? this.yoloMinSize,
|
|
98
|
+
yoloConfThresh: yoloConfThresh ?? this.yoloConfThresh,
|
|
99
|
+
yoloMaxDets: yoloMaxDets ?? this.yoloMaxDets,
|
|
100
|
+
yoloModelFilename: yoloModelFilename ?? this.yoloModelFilename,
|
|
101
|
+
classifierModelFilename:
|
|
102
|
+
classifierModelFilename ?? this.classifierModelFilename,
|
|
103
|
+
deterrentSoundFile: deterrentSoundFile ?? this.deterrentSoundFile,
|
|
104
|
+
fileStabilizationExtraWait:
|
|
105
|
+
fileStabilizationExtraWait ?? this.fileStabilizationExtraWait,
|
|
106
|
+
playSound: playSound ?? this.playSound,
|
|
107
|
+
volume: volume ?? this.volume,
|
|
108
|
+
cameras: cameras ?? this.cameras,
|
|
109
|
+
plugs: plugs ?? this.plugs,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
class Status {
|
|
2
|
+
final String status;
|
|
3
|
+
final String version;
|
|
4
|
+
final int directoriesCount;
|
|
5
|
+
final String host;
|
|
6
|
+
final int port;
|
|
7
|
+
final int uptimeSeconds;
|
|
8
|
+
|
|
9
|
+
Status({
|
|
10
|
+
required this.status,
|
|
11
|
+
required this.version,
|
|
12
|
+
required this.directoriesCount,
|
|
13
|
+
required this.host,
|
|
14
|
+
required this.port,
|
|
15
|
+
required this.uptimeSeconds,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
factory Status.fromJson(Map<String, dynamic> json) {
|
|
19
|
+
return Status(
|
|
20
|
+
status: json['status'] as String? ?? 'unknown',
|
|
21
|
+
version: json['version'] as String? ?? '0.0.0',
|
|
22
|
+
directoriesCount: json['directories_count'] as int? ?? 0,
|
|
23
|
+
host: json['host'] as String? ?? 'localhost',
|
|
24
|
+
port: json['port'] as int? ?? 5000,
|
|
25
|
+
uptimeSeconds: json['uptime_seconds'] as int? ?? 0,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
Map<String, dynamic> toJson() {
|
|
30
|
+
return {
|
|
31
|
+
'status': status,
|
|
32
|
+
'version': version,
|
|
33
|
+
'directories_count': directoriesCount,
|
|
34
|
+
'host': host,
|
|
35
|
+
'port': port,
|
|
36
|
+
'uptime_seconds': uptimeSeconds,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
bool get isRunning => status == 'running';
|
|
41
|
+
|
|
42
|
+
String get uptimeFormatted {
|
|
43
|
+
final days = uptimeSeconds ~/ 86400;
|
|
44
|
+
final hours = (uptimeSeconds % 86400) ~/ 3600;
|
|
45
|
+
final minutes = (uptimeSeconds % 3600) ~/ 60;
|
|
46
|
+
final seconds = uptimeSeconds % 60;
|
|
47
|
+
|
|
48
|
+
if (days > 0) {
|
|
49
|
+
return '${days}d ${hours}h ${minutes}m';
|
|
50
|
+
} else if (hours > 0) {
|
|
51
|
+
return '${hours}h ${minutes}m ${seconds}s';
|
|
52
|
+
} else if (minutes > 0) {
|
|
53
|
+
return '${minutes}m ${seconds}s';
|
|
54
|
+
} else {
|
|
55
|
+
return '${seconds}s';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|