neoagent 2.3.1-beta.2 → 2.3.1-beta.21

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.
Files changed (264) hide show
  1. package/.env.example +39 -0
  2. package/README.md +2 -0
  3. package/docs/capabilities.md +2 -2
  4. package/docs/configuration.md +13 -5
  5. package/docs/integrations.md +4 -1
  6. package/flutter_app/.metadata +42 -0
  7. package/flutter_app/README.md +21 -0
  8. package/flutter_app/analysis_options.yaml +32 -0
  9. package/flutter_app/android/app/build.gradle.kts +109 -0
  10. package/flutter_app/android/app/src/debug/AndroidManifest.xml +7 -0
  11. package/flutter_app/android/app/src/main/AndroidManifest.xml +147 -0
  12. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/MainActivity.kt +747 -0
  13. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthConnectGateway.kt +280 -0
  14. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncNotifications.kt +113 -0
  15. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncPayload.kt +57 -0
  16. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncScheduler.kt +78 -0
  17. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncWorker.kt +253 -0
  18. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/PermissionsRationaleActivity.kt +46 -0
  19. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingBootReceiver.kt +21 -0
  20. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingForegroundService.kt +586 -0
  21. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingStateStore.kt +78 -0
  22. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingUploadClient.kt +104 -0
  23. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/AiHomeWidgetProvider.kt +457 -0
  24. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/AiWidgetStore.kt +194 -0
  25. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/VoiceLaunchWidgetProvider.kt +67 -0
  26. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetConfigActivity.kt +228 -0
  27. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetSyncScheduler.kt +72 -0
  28. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetSyncWorker.kt +186 -0
  29. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetTaskRunWorker.kt +210 -0
  30. package/flutter_app/android/app/src/main/res/drawable/launch_background.xml +12 -0
  31. package/flutter_app/android/app/src/main/res/drawable/neoagent_ai_widget_bg.xml +11 -0
  32. package/flutter_app/android/app/src/main/res/drawable/neoagent_ai_widget_task_bg.xml +8 -0
  33. package/flutter_app/android/app/src/main/res/drawable-v21/launch_background.xml +12 -0
  34. package/flutter_app/android/app/src/main/res/layout/neoagent_ai_widget.xml +138 -0
  35. package/flutter_app/android/app/src/main/res/layout/neoagent_ai_widget_task_row.xml +52 -0
  36. package/flutter_app/android/app/src/main/res/layout/neoagent_voice_widget.xml +49 -0
  37. package/flutter_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  38. package/flutter_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  39. package/flutter_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  40. package/flutter_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  41. package/flutter_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  42. package/flutter_app/android/app/src/main/res/values/strings.xml +12 -0
  43. package/flutter_app/android/app/src/main/res/values/styles.xml +18 -0
  44. package/flutter_app/android/app/src/main/res/values-night/styles.xml +18 -0
  45. package/flutter_app/android/app/src/main/res/xml/file_paths.xml +6 -0
  46. package/flutter_app/android/app/src/main/res/xml/neoagent_ai_widget_info.xml +12 -0
  47. package/flutter_app/android/app/src/main/res/xml/neoagent_voice_widget_info.xml +12 -0
  48. package/flutter_app/android/app/src/profile/AndroidManifest.xml +7 -0
  49. package/flutter_app/android/build.gradle.kts +24 -0
  50. package/flutter_app/android/ci-release.keystore +0 -0
  51. package/flutter_app/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  52. package/flutter_app/android/gradle.properties +3 -0
  53. package/flutter_app/android/key.properties +4 -0
  54. package/flutter_app/android/settings.gradle.kts +26 -0
  55. package/flutter_app/assets/branding/app_icon_1024.png +0 -0
  56. package/flutter_app/assets/branding/app_icon_128.png +0 -0
  57. package/flutter_app/assets/branding/app_icon_192.png +0 -0
  58. package/flutter_app/assets/branding/app_icon_256.png +0 -0
  59. package/flutter_app/assets/branding/app_icon_32.png +0 -0
  60. package/flutter_app/assets/branding/app_icon_512.png +0 -0
  61. package/flutter_app/assets/branding/app_icon_64.png +0 -0
  62. package/flutter_app/assets/branding/tray_icon_template.png +0 -0
  63. package/flutter_app/lib/features/location/location_service.dart +119 -0
  64. package/flutter_app/lib/features/notifications/notification_interceptor.dart +97 -0
  65. package/flutter_app/lib/main.dart +23057 -0
  66. package/flutter_app/lib/main_app_shell.dart +1682 -0
  67. package/flutter_app/lib/main_integrations.dart +931 -0
  68. package/flutter_app/lib/main_launcher.dart +959 -0
  69. package/flutter_app/lib/main_launcher_entry.dart +5 -0
  70. package/flutter_app/lib/main_models.dart +3473 -0
  71. package/flutter_app/lib/main_shared.dart +2861 -0
  72. package/flutter_app/lib/main_theme.dart +204 -0
  73. package/flutter_app/lib/main_voice_assistant.dart +831 -0
  74. package/flutter_app/lib/src/android_apk_drop_zone.dart +32 -0
  75. package/flutter_app/lib/src/android_apk_drop_zone_stub.dart +16 -0
  76. package/flutter_app/lib/src/android_apk_drop_zone_web.dart +348 -0
  77. package/flutter_app/lib/src/android_app_installer.dart +22 -0
  78. package/flutter_app/lib/src/android_app_installer_io.dart +122 -0
  79. package/flutter_app/lib/src/android_app_installer_stub.dart +21 -0
  80. package/flutter_app/lib/src/android_launcher_bridge.dart +239 -0
  81. package/flutter_app/lib/src/app_launch_bridge.dart +29 -0
  82. package/flutter_app/lib/src/app_release_updater.dart +511 -0
  83. package/flutter_app/lib/src/backend_client.dart +1833 -0
  84. package/flutter_app/lib/src/desktop_companion.dart +2 -0
  85. package/flutter_app/lib/src/desktop_companion_actions.dart +586 -0
  86. package/flutter_app/lib/src/desktop_companion_io.dart +538 -0
  87. package/flutter_app/lib/src/desktop_companion_stub.dart +59 -0
  88. package/flutter_app/lib/src/desktop_native_bridge.dart +91 -0
  89. package/flutter_app/lib/src/desktop_screen_capture.dart +21 -0
  90. package/flutter_app/lib/src/desktop_screen_capture_io.dart +142 -0
  91. package/flutter_app/lib/src/desktop_screen_capture_stub.dart +12 -0
  92. package/flutter_app/lib/src/diagnostics_logger.dart +119 -0
  93. package/flutter_app/lib/src/health_bridge.dart +136 -0
  94. package/flutter_app/lib/src/live_voice_capture.dart +85 -0
  95. package/flutter_app/lib/src/messaging_access_summary.dart +46 -0
  96. package/flutter_app/lib/src/network/app_http_client.dart +53 -0
  97. package/flutter_app/lib/src/network/app_http_client_factory.dart +6 -0
  98. package/flutter_app/lib/src/network/app_http_client_io.dart +138 -0
  99. package/flutter_app/lib/src/network/app_http_client_stub.dart +3 -0
  100. package/flutter_app/lib/src/network/app_http_client_web.dart +94 -0
  101. package/flutter_app/lib/src/oauth_launcher.dart +33 -0
  102. package/flutter_app/lib/src/oauth_launcher_io.dart +77 -0
  103. package/flutter_app/lib/src/oauth_launcher_stub.dart +33 -0
  104. package/flutter_app/lib/src/oauth_launcher_web.dart +107 -0
  105. package/flutter_app/lib/src/recording_bridge.dart +232 -0
  106. package/flutter_app/lib/src/recording_bridge_io.dart +1019 -0
  107. package/flutter_app/lib/src/recording_bridge_stub.dart +120 -0
  108. package/flutter_app/lib/src/recording_bridge_web.dart +689 -0
  109. package/flutter_app/lib/src/recording_payloads.dart +86 -0
  110. package/flutter_app/lib/src/theme/palette.dart +81 -0
  111. package/flutter_app/lib/src/widget_bridge.dart +49 -0
  112. package/flutter_app/linux/CMakeLists.txt +128 -0
  113. package/flutter_app/linux/flutter/CMakeLists.txt +88 -0
  114. package/flutter_app/linux/flutter/generated_plugin_registrant.cc +43 -0
  115. package/flutter_app/linux/flutter/generated_plugin_registrant.h +15 -0
  116. package/flutter_app/linux/flutter/generated_plugins.cmake +31 -0
  117. package/flutter_app/linux/runner/CMakeLists.txt +26 -0
  118. package/flutter_app/linux/runner/main.cc +6 -0
  119. package/flutter_app/linux/runner/my_application.cc +144 -0
  120. package/flutter_app/linux/runner/my_application.h +18 -0
  121. package/flutter_app/linux/runner/resources/app_icon.png +0 -0
  122. package/flutter_app/macos/Flutter/Flutter-Debug.xcconfig +2 -0
  123. package/flutter_app/macos/Flutter/Flutter-Release.xcconfig +2 -0
  124. package/flutter_app/macos/Flutter/GeneratedPluginRegistrant.swift +40 -0
  125. package/flutter_app/macos/Podfile +42 -0
  126. package/flutter_app/macos/Podfile.lock +87 -0
  127. package/flutter_app/macos/Runner/AppDelegate.swift +576 -0
  128. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
  129. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
  130. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
  131. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
  132. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
  133. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
  134. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
  135. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
  136. package/flutter_app/macos/Runner/Base.lproj/MainMenu.xib +342 -0
  137. package/flutter_app/macos/Runner/Configs/AppInfo.xcconfig +14 -0
  138. package/flutter_app/macos/Runner/Configs/Debug.xcconfig +2 -0
  139. package/flutter_app/macos/Runner/Configs/Release.xcconfig +2 -0
  140. package/flutter_app/macos/Runner/Configs/Warnings.xcconfig +13 -0
  141. package/flutter_app/macos/Runner/DebugProfile.entitlements +16 -0
  142. package/flutter_app/macos/Runner/Info.plist +36 -0
  143. package/flutter_app/macos/Runner/MainFlutterWindow.swift +19 -0
  144. package/flutter_app/macos/Runner/Release.entitlements +12 -0
  145. package/flutter_app/macos/Runner.xcodeproj/project.pbxproj +801 -0
  146. package/flutter_app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  147. package/flutter_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +99 -0
  148. package/flutter_app/macos/Runner.xcworkspace/contents.xcworkspacedata +10 -0
  149. package/flutter_app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  150. package/flutter_app/macos/RunnerTests/RunnerTests.swift +12 -0
  151. package/flutter_app/patch_strings.py +12 -0
  152. package/flutter_app/pubspec.lock +1088 -0
  153. package/flutter_app/pubspec.yaml +53 -0
  154. package/flutter_app/test/messaging_access_summary_test.dart +22 -0
  155. package/flutter_app/test/recording_payloads_test.dart +53 -0
  156. package/flutter_app/third_party/desktop_audio_capture/LICENSE +21 -0
  157. package/flutter_app/third_party/desktop_audio_capture/README.md +262 -0
  158. package/flutter_app/third_party/desktop_audio_capture/lib/audio_capture.dart +65 -0
  159. package/flutter_app/third_party/desktop_audio_capture/lib/config/mic_audio_config.dart +153 -0
  160. package/flutter_app/third_party/desktop_audio_capture/lib/config/system_adudio_config.dart +110 -0
  161. package/flutter_app/third_party/desktop_audio_capture/lib/mic/mic_audio_capture.dart +461 -0
  162. package/flutter_app/third_party/desktop_audio_capture/lib/model/audio_status.dart +91 -0
  163. package/flutter_app/third_party/desktop_audio_capture/lib/model/decibel_data.dart +106 -0
  164. package/flutter_app/third_party/desktop_audio_capture/lib/model/input_device_type.dart +219 -0
  165. package/flutter_app/third_party/desktop_audio_capture/lib/system/system_audio_capture.dart +336 -0
  166. package/flutter_app/third_party/desktop_audio_capture/linux/CMakeLists.txt +101 -0
  167. package/flutter_app/third_party/desktop_audio_capture/linux/audio_capture_plugin.cc +692 -0
  168. package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/audio_capture_plugin.h +35 -0
  169. package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/mic_capture_plugin.h +36 -0
  170. package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/audio_capture_plugin.h +32 -0
  171. package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/mic_capture_plugin.h +32 -0
  172. package/flutter_app/third_party/desktop_audio_capture/linux/mic_capture_plugin.cc +878 -0
  173. package/flutter_app/third_party/desktop_audio_capture/macos/Classes/AudioCapturePlugin.swift +27 -0
  174. package/flutter_app/third_party/desktop_audio_capture/macos/Classes/MicCapturePlugin.swift +1172 -0
  175. package/flutter_app/third_party/desktop_audio_capture/macos/Classes/SystemCapturePlugin.swift +655 -0
  176. package/flutter_app/third_party/desktop_audio_capture/macos/Resources/PrivacyInfo.xcprivacy +12 -0
  177. package/flutter_app/third_party/desktop_audio_capture/macos/desktop_audio_capture.podspec +30 -0
  178. package/flutter_app/third_party/desktop_audio_capture/pubspec.yaml +87 -0
  179. package/flutter_app/third_party/desktop_audio_capture/windows/CMakeLists.txt +105 -0
  180. package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.cpp +80 -0
  181. package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.h +31 -0
  182. package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin_c_api.cpp +12 -0
  183. package/flutter_app/third_party/desktop_audio_capture/windows/include/audio_capture/audio_capture_plugin_c_api.h +23 -0
  184. package/flutter_app/third_party/desktop_audio_capture/windows/include/desktop_audio_capture/audio_capture_plugin.h +25 -0
  185. package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.cpp +1117 -0
  186. package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.h +115 -0
  187. package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.cpp +777 -0
  188. package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.h +87 -0
  189. package/flutter_app/third_party/flutter_secure_storage_linux/linux/CMakeLists.txt +30 -0
  190. package/flutter_app/third_party/flutter_secure_storage_linux/linux/flutter_secure_storage_linux_plugin.cc +215 -0
  191. package/flutter_app/third_party/flutter_secure_storage_linux/linux/include/flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h +27 -0
  192. package/flutter_app/third_party/flutter_secure_storage_linux/pubspec.yaml +20 -0
  193. package/flutter_app/tool/generate_desktop_branding.py +219 -0
  194. package/flutter_app/web/favicon.png +0 -0
  195. package/flutter_app/web/favicon.svg +12 -0
  196. package/flutter_app/web/icons/Icon-192.png +0 -0
  197. package/flutter_app/web/icons/Icon-512.png +0 -0
  198. package/flutter_app/web/icons/Icon-maskable-192.png +0 -0
  199. package/flutter_app/web/icons/Icon-maskable-512.png +0 -0
  200. package/flutter_app/web/index.html +39 -0
  201. package/flutter_app/web/manifest.json +35 -0
  202. package/flutter_app/windows/CMakeLists.txt +108 -0
  203. package/flutter_app/windows/flutter/CMakeLists.txt +109 -0
  204. package/flutter_app/windows/flutter/generated_plugin_registrant.cc +47 -0
  205. package/flutter_app/windows/flutter/generated_plugin_registrant.h +15 -0
  206. package/flutter_app/windows/flutter/generated_plugins.cmake +35 -0
  207. package/flutter_app/windows/runner/CMakeLists.txt +41 -0
  208. package/flutter_app/windows/runner/Runner.rc +121 -0
  209. package/flutter_app/windows/runner/flutter_window.cpp +533 -0
  210. package/flutter_app/windows/runner/flutter_window.h +37 -0
  211. package/flutter_app/windows/runner/main.cpp +53 -0
  212. package/flutter_app/windows/runner/resource.h +16 -0
  213. package/flutter_app/windows/runner/resources/app_icon.ico +0 -0
  214. package/flutter_app/windows/runner/runner.exe.manifest +14 -0
  215. package/flutter_app/windows/runner/utils.cpp +65 -0
  216. package/flutter_app/windows/runner/utils.h +19 -0
  217. package/flutter_app/windows/runner/win32_window.cpp +299 -0
  218. package/flutter_app/windows/runner/win32_window.h +102 -0
  219. package/lib/manager.js +231 -7
  220. package/package.json +3 -1
  221. package/server/db/database.js +68 -0
  222. package/server/http/middleware.js +50 -0
  223. package/server/http/routes.js +3 -1
  224. package/server/index.js +1 -0
  225. package/server/public/.last_build_id +1 -1
  226. package/server/public/assets/NOTICES +61 -0
  227. package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
  228. package/server/public/flutter_bootstrap.js +1 -1
  229. package/server/public/main.dart.js +65262 -64422
  230. package/server/routes/integrations.js +86 -0
  231. package/server/routes/memory.js +11 -2
  232. package/server/routes/screenHistory.js +46 -0
  233. package/server/routes/triggers.js +81 -0
  234. package/server/services/ai/models.js +30 -0
  235. package/server/services/ai/providers/githubCopilot.js +97 -0
  236. package/server/services/ai/providers/openai.js +2 -1
  237. package/server/services/ai/providers/openaiCodex.js +31 -0
  238. package/server/services/ai/settings.js +20 -0
  239. package/server/services/ai/systemPrompt.js +1 -1
  240. package/server/services/ai/tools.js +35 -6
  241. package/server/services/browser/controller.js +47 -3
  242. package/server/services/desktop/screenRecorder.js +172 -0
  243. package/server/services/integrations/env.js +5 -0
  244. package/server/services/integrations/github/common.js +106 -0
  245. package/server/services/integrations/github/provider.js +499 -0
  246. package/server/services/integrations/github/repos.js +1124 -0
  247. package/server/services/integrations/home_assistant/provider.js +306 -26
  248. package/server/services/integrations/manager.js +63 -7
  249. package/server/services/integrations/oauth_provider.js +13 -6
  250. package/server/services/integrations/provider_config_store.js +76 -0
  251. package/server/services/integrations/registry.js +4 -0
  252. package/server/services/integrations/trello/provider.js +744 -0
  253. package/server/services/integrations/whatsapp/provider.js +6 -2
  254. package/server/services/manager.js +22 -0
  255. package/server/services/memory/manager.js +39 -2
  256. package/server/services/skills/base_catalog.js +33 -0
  257. package/server/services/tasks/adapters/index.js +1 -0
  258. package/server/services/tasks/adapters/manual.js +12 -0
  259. package/server/services/tasks/runtime.js +1 -1
  260. package/server/services/voice/openaiClient.js +4 -1
  261. package/server/services/voice/providers.js +2 -1
  262. package/server/services/widgets/service.js +49 -4
  263. package/server/utils/local_secrets.js +56 -0
  264. package/server/utils/logger.js +37 -9
@@ -0,0 +1,87 @@
1
+ #ifndef FLUTTER_PLUGIN_SYSTEM_AUDIO_CAPTURE_PLUGIN_H_
2
+ #define FLUTTER_PLUGIN_SYSTEM_AUDIO_CAPTURE_PLUGIN_H_
3
+
4
+ #include <flutter/event_channel.h>
5
+ #include <flutter/method_channel.h>
6
+ #include <flutter/plugin_registrar_windows.h>
7
+ #include <flutter/standard_method_codec.h>
8
+
9
+ #include <memory>
10
+ #include <mutex>
11
+ #include <thread>
12
+ #include <atomic>
13
+ #include <vector>
14
+
15
+ // Include Windows headers for WAVEFORMATEX
16
+ #include <mmsystem.h>
17
+
18
+ // Forward declarations for WASAPI interfaces
19
+ struct IAudioClient;
20
+ struct IAudioCaptureClient;
21
+ struct IMMDevice;
22
+
23
+ namespace audio_capture {
24
+
25
+ class SystemAudioCapturePlugin : public flutter::Plugin {
26
+ public:
27
+ static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar);
28
+
29
+ SystemAudioCapturePlugin(flutter::PluginRegistrarWindows *registrar);
30
+ ~SystemAudioCapturePlugin();
31
+
32
+ // Disallow copy and assign.
33
+ SystemAudioCapturePlugin(const SystemAudioCapturePlugin&) = delete;
34
+ SystemAudioCapturePlugin& operator=(const SystemAudioCapturePlugin&) = delete;
35
+
36
+ void HandleMethodCall(
37
+ const flutter::MethodCall<flutter::EncodableValue> &method_call,
38
+ std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
39
+
40
+ private:
41
+ bool StartCapture(const flutter::EncodableMap* args);
42
+ bool StopCapture();
43
+ void CaptureThread();
44
+ void SetThreadPriority();
45
+ double CalculateDecibel(const int16_t* samples, size_t sample_count);
46
+ void ApplyGainBoostAndConvertToMono(const int16_t* input, int16_t* output,
47
+ size_t frame_count, int input_channels,
48
+ float gain_boost);
49
+ void SendStatusUpdate(bool is_active);
50
+ void SendDecibelUpdate(double decibel);
51
+
52
+ flutter::PluginRegistrarWindows* registrar_;
53
+ std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> method_channel_;
54
+ std::unique_ptr<flutter::EventChannel<flutter::EncodableValue>> event_channel_;
55
+ std::unique_ptr<flutter::EventChannel<flutter::EncodableValue>> status_event_channel_;
56
+ std::unique_ptr<flutter::EventChannel<flutter::EncodableValue>> decibel_event_channel_;
57
+
58
+ std::unique_ptr<flutter::EventSink<flutter::EncodableValue>> event_sink_;
59
+ std::unique_ptr<flutter::EventSink<flutter::EncodableValue>> status_event_sink_;
60
+ std::unique_ptr<flutter::EventSink<flutter::EncodableValue>> decibel_event_sink_;
61
+
62
+ std::mutex mutex_;
63
+ std::atomic<bool> is_capturing_;
64
+ std::atomic<bool> should_stop_;
65
+ std::thread capture_thread_;
66
+
67
+ // Audio configuration
68
+ int sample_rate_;
69
+ int channels_;
70
+ int bits_per_sample_;
71
+ int chunk_duration_ms_;
72
+ float gain_boost_;
73
+ float input_volume_;
74
+
75
+ // WASAPI interfaces
76
+ IAudioClient* audio_client_;
77
+ IAudioCaptureClient* capture_client_;
78
+ IMMDevice* device_;
79
+ WAVEFORMATEX* mix_format_;
80
+ UINT32 buffer_frame_count_;
81
+ bool com_initialized_; // Track if we initialized COM
82
+ };
83
+
84
+ } // namespace audio_capture
85
+
86
+ #endif // FLUTTER_PLUGIN_SYSTEM_AUDIO_CAPTURE_PLUGIN_H_
87
+
@@ -0,0 +1,30 @@
1
+ cmake_minimum_required(VERSION 3.10)
2
+ set(PROJECT_NAME "flutter_secure_storage_linux")
3
+ project(${PROJECT_NAME} LANGUAGES CXX)
4
+
5
+ set(PLUGIN_NAME "flutter_secure_storage_linux_plugin")
6
+
7
+ add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
8
+
9
+ add_library(${PLUGIN_NAME} SHARED
10
+ "flutter_secure_storage_linux_plugin.cc"
11
+ )
12
+
13
+ apply_standard_settings(${PLUGIN_NAME})
14
+
15
+ set_target_properties(${PLUGIN_NAME} PROPERTIES
16
+ CXX_VISIBILITY_PRESET hidden
17
+ )
18
+
19
+ target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
20
+ target_include_directories(${PLUGIN_NAME} INTERFACE
21
+ "${CMAKE_CURRENT_SOURCE_DIR}/include"
22
+ )
23
+
24
+ target_link_libraries(${PLUGIN_NAME} PRIVATE flutter)
25
+ target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK)
26
+
27
+ set(flutter_secure_storage_bundled_libraries
28
+ ""
29
+ PARENT_SCOPE
30
+ )
@@ -0,0 +1,215 @@
1
+ #include "include/flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h"
2
+
3
+ #include <flutter_linux/flutter_linux.h>
4
+ #include <glib.h>
5
+ #include <gtk/gtk.h>
6
+
7
+ #include <cstdio>
8
+ #include <string>
9
+
10
+ #define flutter_secure_storage_linux_plugin(obj) \
11
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
12
+ flutter_secure_storage_linux_plugin_get_type(), \
13
+ FlutterSecureStorageLinuxPlugin))
14
+
15
+ namespace {
16
+
17
+ constexpr const char *kChannelName =
18
+ "plugins.it_nomads.com/flutter_secure_storage";
19
+ constexpr const char *kGroupName = "secure_storage";
20
+
21
+ std::string GetStoragePath() {
22
+ const gchar *config_dir = g_get_user_config_dir();
23
+ gchar *directory = g_build_filename(config_dir, APPLICATION_ID, nullptr);
24
+ g_mkdir_with_parents(directory, 0700);
25
+ gchar *path = g_build_filename(directory, "flutter_secure_storage.ini", nullptr);
26
+ std::string result(path);
27
+ g_free(path);
28
+ g_free(directory);
29
+ return result;
30
+ }
31
+
32
+ GKeyFile *LoadKeyFile() {
33
+ GKeyFile *key_file = g_key_file_new();
34
+ const std::string path = GetStoragePath();
35
+ GError *error = nullptr;
36
+ g_key_file_load_from_file(
37
+ key_file,
38
+ path.c_str(),
39
+ static_cast<GKeyFileFlags>(G_KEY_FILE_KEEP_COMMENTS |
40
+ G_KEY_FILE_KEEP_TRANSLATIONS),
41
+ &error);
42
+ if (error != nullptr) {
43
+ g_error_free(error);
44
+ }
45
+ return key_file;
46
+ }
47
+
48
+ bool SaveKeyFile(GKeyFile *key_file, gchar **error_message) {
49
+ gsize length = 0;
50
+ GError *error = nullptr;
51
+ gchar *data = g_key_file_to_data(key_file, &length, &error);
52
+ if (error != nullptr) {
53
+ *error_message = g_strdup(error->message);
54
+ g_error_free(error);
55
+ return false;
56
+ }
57
+
58
+ const std::string path = GetStoragePath();
59
+ if (!g_file_set_contents(path.c_str(), data, static_cast<gssize>(length), &error)) {
60
+ *error_message = g_strdup(error->message);
61
+ g_error_free(error);
62
+ g_free(data);
63
+ return false;
64
+ }
65
+
66
+ g_free(data);
67
+ return true;
68
+ }
69
+
70
+ FlMethodResponse *BuildErrorResponse(const gchar *code, const gchar *message) {
71
+ return FL_METHOD_RESPONSE(
72
+ fl_method_error_response_new(code, message, nullptr));
73
+ }
74
+
75
+ } // namespace
76
+
77
+ struct _FlutterSecureStorageLinuxPlugin {
78
+ GObject parent_instance;
79
+ };
80
+
81
+ G_DEFINE_TYPE(FlutterSecureStorageLinuxPlugin,
82
+ flutter_secure_storage_linux_plugin,
83
+ g_object_get_type())
84
+
85
+ static void flutter_secure_storage_linux_plugin_handle_method_call(
86
+ FlutterSecureStorageLinuxPlugin *self,
87
+ FlMethodCall *method_call) {
88
+ g_autoptr(FlMethodResponse) response = nullptr;
89
+
90
+ const gchar *method = fl_method_call_get_name(method_call);
91
+ FlValue *args = fl_method_call_get_args(method_call);
92
+
93
+ if (fl_value_get_type(args) != FL_VALUE_TYPE_MAP) {
94
+ response = BuildErrorResponse("Bad arguments",
95
+ "args given to function is not a map");
96
+ fl_method_call_respond(method_call, response, nullptr);
97
+ return;
98
+ }
99
+
100
+ FlValue *key = fl_value_lookup_string(args, "key");
101
+ FlValue *value = fl_value_lookup_string(args, "value");
102
+ const gchar *key_string = key == nullptr ? nullptr : fl_value_get_string(key);
103
+ const gchar *value_string =
104
+ value == nullptr ? nullptr : fl_value_get_string(value);
105
+
106
+ g_autoptr(GKeyFile) key_file = LoadKeyFile();
107
+
108
+ if (strcmp(method, "write") == 0) {
109
+ if (key_string == nullptr || value_string == nullptr) {
110
+ response = BuildErrorResponse("Bad arguments", "Key or Value was null");
111
+ } else {
112
+ g_key_file_set_string(key_file, kGroupName, key_string, value_string);
113
+ gchar *error_message = nullptr;
114
+ if (!SaveKeyFile(key_file, &error_message)) {
115
+ response = BuildErrorResponse("Storage error", error_message);
116
+ g_free(error_message);
117
+ } else {
118
+ response = FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
119
+ }
120
+ }
121
+ } else if (strcmp(method, "read") == 0) {
122
+ if (key_string == nullptr) {
123
+ response = BuildErrorResponse("Bad arguments", "Key is null");
124
+ } else if (!g_key_file_has_key(key_file, kGroupName, key_string, nullptr)) {
125
+ response = FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
126
+ } else {
127
+ gchar *stored_value = g_key_file_get_string(key_file, kGroupName, key_string, nullptr);
128
+ g_autoptr(FlValue) result = fl_value_new_string(stored_value);
129
+ g_free(stored_value);
130
+ response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
131
+ }
132
+ } else if (strcmp(method, "readAll") == 0) {
133
+ gsize key_count = 0;
134
+ g_auto(GStrv) keys = g_key_file_get_keys(key_file, kGroupName, &key_count, nullptr);
135
+ g_autoptr(FlValue) result = fl_value_new_map();
136
+ for (gsize i = 0; i < key_count; ++i) {
137
+ gchar *stored_value = g_key_file_get_string(key_file, kGroupName, keys[i], nullptr);
138
+ fl_value_set_string_take(result, keys[i], fl_value_new_string(stored_value));
139
+ g_free(stored_value);
140
+ }
141
+ response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
142
+ } else if (strcmp(method, "delete") == 0) {
143
+ if (key_string == nullptr) {
144
+ response = BuildErrorResponse("Bad arguments", "Key is null");
145
+ } else {
146
+ g_key_file_remove_key(key_file, kGroupName, key_string, nullptr);
147
+ gchar *error_message = nullptr;
148
+ if (!SaveKeyFile(key_file, &error_message)) {
149
+ response = BuildErrorResponse("Storage error", error_message);
150
+ g_free(error_message);
151
+ } else {
152
+ response = FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
153
+ }
154
+ }
155
+ } else if (strcmp(method, "deleteAll") == 0) {
156
+ g_key_file_remove_group(key_file, kGroupName, nullptr);
157
+ gchar *error_message = nullptr;
158
+ if (!SaveKeyFile(key_file, &error_message)) {
159
+ response = BuildErrorResponse("Storage error", error_message);
160
+ g_free(error_message);
161
+ } else {
162
+ response = FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
163
+ }
164
+ } else if (strcmp(method, "containsKey") == 0) {
165
+ if (key_string == nullptr) {
166
+ response = BuildErrorResponse("Bad arguments", "Key is null");
167
+ } else {
168
+ g_autoptr(FlValue) result =
169
+ fl_value_new_bool(g_key_file_has_key(key_file, kGroupName, key_string, nullptr));
170
+ response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
171
+ }
172
+ } else {
173
+ response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
174
+ }
175
+
176
+ fl_method_call_respond(method_call, response, nullptr);
177
+ }
178
+
179
+ static void flutter_secure_storage_linux_plugin_dispose(GObject *object) {
180
+ G_OBJECT_CLASS(flutter_secure_storage_linux_plugin_parent_class)
181
+ ->dispose(object);
182
+ }
183
+
184
+ static void flutter_secure_storage_linux_plugin_class_init(
185
+ FlutterSecureStorageLinuxPluginClass *klass) {
186
+ G_OBJECT_CLASS(klass)->dispose =
187
+ flutter_secure_storage_linux_plugin_dispose;
188
+ }
189
+
190
+ static void flutter_secure_storage_linux_plugin_init(
191
+ FlutterSecureStorageLinuxPlugin *self) {}
192
+
193
+ static void method_call_cb(FlMethodChannel *channel,
194
+ FlMethodCall *method_call,
195
+ gpointer user_data) {
196
+ FlutterSecureStorageLinuxPlugin *plugin =
197
+ flutter_secure_storage_linux_plugin(user_data);
198
+ flutter_secure_storage_linux_plugin_handle_method_call(plugin, method_call);
199
+ }
200
+
201
+ void flutter_secure_storage_linux_plugin_register_with_registrar(
202
+ FlPluginRegistrar *registrar) {
203
+ FlutterSecureStorageLinuxPlugin *plugin =
204
+ flutter_secure_storage_linux_plugin(
205
+ g_object_new(flutter_secure_storage_linux_plugin_get_type(), nullptr));
206
+
207
+ g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
208
+ g_autoptr(FlMethodChannel) channel = fl_method_channel_new(
209
+ fl_plugin_registrar_get_messenger(registrar),
210
+ kChannelName,
211
+ FL_METHOD_CODEC(codec));
212
+ fl_method_channel_set_method_call_handler(
213
+ channel, method_call_cb, g_object_ref(plugin), g_object_unref);
214
+ g_object_unref(plugin);
215
+ }
@@ -0,0 +1,27 @@
1
+ #ifndef FLUTTER_PLUGIN_FLUTTER_SECURE_STORAGE_LINUX_PLUGIN_H_
2
+ #define FLUTTER_PLUGIN_FLUTTER_SECURE_STORAGE_LINUX_PLUGIN_H_
3
+
4
+ #include <flutter_linux/flutter_linux.h>
5
+
6
+ G_BEGIN_DECLS
7
+
8
+ #ifdef FLUTTER_PLUGIN_IMPL
9
+ #define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default")))
10
+ #else
11
+ #define FLUTTER_PLUGIN_EXPORT
12
+ #endif
13
+
14
+ typedef struct _FlutterSecureStorageLinuxPlugin FlutterSecureStorageLinuxPlugin;
15
+ typedef struct {
16
+ GObjectClass parent_class;
17
+ } FlutterSecureStorageLinuxPluginClass;
18
+
19
+ FLUTTER_PLUGIN_EXPORT GType flutter_secure_storage_linux_plugin_get_type();
20
+
21
+ FLUTTER_PLUGIN_EXPORT void
22
+ flutter_secure_storage_linux_plugin_register_with_registrar(
23
+ FlPluginRegistrar *registrar);
24
+
25
+ G_END_DECLS
26
+
27
+ #endif
@@ -0,0 +1,20 @@
1
+ name: flutter_secure_storage_linux
2
+ description: Local Linux implementation of flutter_secure_storage without libsecret.
3
+ version: 1.2.3
4
+ publish_to: none
5
+
6
+ environment:
7
+ sdk: ">=3.0.0 <4.0.0"
8
+ flutter: ">=3.0.0"
9
+
10
+ dependencies:
11
+ flutter:
12
+ sdk: flutter
13
+ flutter_secure_storage_platform_interface: ^1.1.2
14
+
15
+ flutter:
16
+ plugin:
17
+ implements: flutter_secure_storage
18
+ platforms:
19
+ linux:
20
+ pluginClass: FlutterSecureStorageLinuxPlugin
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env python3
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ from pathlib import Path
7
+
8
+ from PIL import Image, ImageDraw, ImageFilter
9
+
10
+
11
+ ROOT = Path(__file__).resolve().parents[1]
12
+ BRANDING_DIR = ROOT / "assets" / "branding"
13
+ WEB_DIR = ROOT / "web"
14
+ WEB_ICONS_DIR = WEB_DIR / "icons"
15
+ MAC_ICON_DIR = ROOT / "macos" / "Runner" / "Assets.xcassets" / "AppIcon.appiconset"
16
+ WINDOWS_ICON_PATH = ROOT / "windows" / "runner" / "resources" / "app_icon.ico"
17
+ LINUX_ICON_DIR = ROOT / "linux" / "runner" / "resources"
18
+ ANDROID_RES_DIR = ROOT / "android" / "app" / "src" / "main" / "res"
19
+ SERVER_PUBLIC_DIR = ROOT.parent / "server" / "public"
20
+ SERVER_PUBLIC_ICONS_DIR = SERVER_PUBLIC_DIR / "icons"
21
+
22
+ ACCENT = (143, 109, 62)
23
+ ACCENT_ALT = (47, 125, 110)
24
+ WHITE = (255, 255, 255, 255)
25
+ TRANSPARENT = (0, 0, 0, 0)
26
+
27
+
28
+ def lerp(a: float, b: float, t: float) -> float:
29
+ return a + (b - a) * t
30
+
31
+
32
+ def gradient_background(size: int) -> Image.Image:
33
+ img = Image.new("RGBA", (size, size), TRANSPARENT)
34
+ px = img.load()
35
+ for y in range(size):
36
+ for x in range(size):
37
+ tx = x / max(size - 1, 1)
38
+ ty = y / max(size - 1, 1)
39
+ t = (tx + ty) / 2
40
+ px[x, y] = (
41
+ int(lerp(ACCENT[0], ACCENT_ALT[0], t)),
42
+ int(lerp(ACCENT[1], ACCENT_ALT[1], t)),
43
+ int(lerp(ACCENT[2], ACCENT_ALT[2], t)),
44
+ 255,
45
+ )
46
+ return img
47
+
48
+
49
+ def logo_paths(size: int, padding_ratio: float = 0.18):
50
+ pad = size * padding_ratio
51
+ inner = size - pad * 2
52
+ def point(x: float, y: float) -> tuple[float, float]:
53
+ return (pad + inner * x, pad + inner * y)
54
+
55
+ top = [point(0.5, 0.08), point(0.1, 0.3), point(0.5, 0.52), point(0.9, 0.3)]
56
+ middle = [point(0.1, 0.52), point(0.5, 0.74), point(0.9, 0.52)]
57
+ bottom = [point(0.1, 0.72), point(0.5, 0.94), point(0.9, 0.72)]
58
+ return top, middle, bottom, inner
59
+
60
+
61
+ def draw_logo(draw: ImageDraw.ImageDraw, size: int, color: tuple[int, int, int, int]) -> None:
62
+ top, middle, bottom, inner = logo_paths(size)
63
+ stroke = max(2, round(inner * 0.08))
64
+ draw.polygon(top, fill=color)
65
+ draw.line(middle, fill=color, width=stroke, joint="curve")
66
+ draw.line(bottom, fill=color, width=stroke, joint="curve")
67
+
68
+
69
+ def make_app_icon(size: int) -> Image.Image:
70
+ canvas = Image.new("RGBA", (size, size), TRANSPARENT)
71
+
72
+ shadow = Image.new("RGBA", (size, size), TRANSPARENT)
73
+ shadow_draw = ImageDraw.Draw(shadow)
74
+ offset_y = size * 0.02
75
+ corner = round(size * 0.34)
76
+ shadow_draw.rounded_rectangle(
77
+ (size * 0.07, size * 0.07 + offset_y, size * 0.93, size * 0.93 + offset_y),
78
+ radius=corner,
79
+ fill=(0, 0, 0, 72),
80
+ )
81
+ shadow = shadow.filter(ImageFilter.GaussianBlur(radius=max(2, size * 0.04)))
82
+ canvas.alpha_composite(shadow)
83
+
84
+ base_mask = Image.new("L", (size, size), 0)
85
+ mask_draw = ImageDraw.Draw(base_mask)
86
+ base_rect = (size * 0.08, size * 0.08, size * 0.92, size * 0.92)
87
+ mask_draw.rounded_rectangle(base_rect, radius=corner, fill=255)
88
+
89
+ base = gradient_background(size)
90
+ clipped = Image.new("RGBA", (size, size), TRANSPARENT)
91
+ clipped.paste(base, mask=base_mask)
92
+ canvas.alpha_composite(clipped)
93
+
94
+ ring = Image.new("RGBA", (size, size), TRANSPARENT)
95
+ ring_draw = ImageDraw.Draw(ring)
96
+ ring_draw.rounded_rectangle(
97
+ base_rect,
98
+ radius=corner,
99
+ outline=(255, 255, 255, 36),
100
+ width=max(1, round(size * 0.012)),
101
+ )
102
+ canvas.alpha_composite(ring)
103
+
104
+ glyph = Image.new("RGBA", (size, size), TRANSPARENT)
105
+ draw = ImageDraw.Draw(glyph)
106
+ draw_logo(draw, size, WHITE)
107
+ canvas.alpha_composite(glyph)
108
+ return canvas
109
+
110
+
111
+ def make_tray_template(size: int = 64) -> Image.Image:
112
+ img = Image.new("RGBA", (size, size), TRANSPARENT)
113
+ draw = ImageDraw.Draw(img)
114
+ draw_logo(draw, size, (0, 0, 0, 255))
115
+ return img
116
+
117
+
118
+ def ensure_dirs() -> None:
119
+ BRANDING_DIR.mkdir(parents=True, exist_ok=True)
120
+ WEB_ICONS_DIR.mkdir(parents=True, exist_ok=True)
121
+ MAC_ICON_DIR.mkdir(parents=True, exist_ok=True)
122
+ LINUX_ICON_DIR.mkdir(parents=True, exist_ok=True)
123
+ SERVER_PUBLIC_ICONS_DIR.mkdir(parents=True, exist_ok=True)
124
+
125
+
126
+ def write_text(path: Path, content: str) -> None:
127
+ path.write_text(content, encoding="utf-8")
128
+
129
+
130
+ def copy_png(image: Image.Image, path: Path, size: int) -> None:
131
+ path.parent.mkdir(parents=True, exist_ok=True)
132
+ save_png(image, path, size)
133
+
134
+
135
+ def write_favicon_svg(path: Path) -> None:
136
+ svg = f"""<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
137
+ <defs>
138
+ <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
139
+ <stop offset="0%" stop-color="#{ACCENT[0]:02x}{ACCENT[1]:02x}{ACCENT[2]:02x}"/>
140
+ <stop offset="100%" stop-color="#{ACCENT_ALT[0]:02x}{ACCENT_ALT[1]:02x}{ACCENT_ALT[2]:02x}"/>
141
+ </linearGradient>
142
+ </defs>
143
+ <rect x="2.5" y="2.5" width="27" height="27" rx="9" ry="9" fill="url(#bg)" stroke="#ffffff" stroke-opacity="0.16" stroke-width="1"/>
144
+ <polygon points="16,5.7 5.2,11.6 16,17.6 26.8,11.6" fill="white"/>
145
+ <polyline points="5.2,17.6 16,23.5 26.8,17.6" fill="none" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
146
+ <polyline points="5.2,22.7 16,28.1 26.8,22.7" fill="none" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
147
+ </svg>
148
+ """
149
+ write_text(path, svg)
150
+
151
+
152
+ def save_png(image: Image.Image, path: Path, size: int) -> None:
153
+ image.resize((size, size), Image.Resampling.LANCZOS).save(path, format="PNG")
154
+
155
+
156
+ def main() -> None:
157
+ ensure_dirs()
158
+ master = make_app_icon(1024)
159
+
160
+ save_png(master, BRANDING_DIR / "app_icon_1024.png", 1024)
161
+ save_png(master, BRANDING_DIR / "app_icon_512.png", 512)
162
+ save_png(master, BRANDING_DIR / "app_icon_256.png", 256)
163
+ save_png(master, BRANDING_DIR / "app_icon_192.png", 192)
164
+ save_png(master, BRANDING_DIR / "app_icon_128.png", 128)
165
+ save_png(master, BRANDING_DIR / "app_icon_64.png", 64)
166
+ save_png(master, BRANDING_DIR / "app_icon_32.png", 32)
167
+
168
+ tray = make_tray_template(64)
169
+ save_png(tray, BRANDING_DIR / "tray_icon_template.png", 64)
170
+
171
+ icon_sizes = {
172
+ 16: "app_icon_16.png",
173
+ 32: "app_icon_32.png",
174
+ 64: "app_icon_64.png",
175
+ 128: "app_icon_128.png",
176
+ 256: "app_icon_256.png",
177
+ 512: "app_icon_512.png",
178
+ 1024: "app_icon_1024.png",
179
+ }
180
+ for size, filename in icon_sizes.items():
181
+ save_png(master, MAC_ICON_DIR / filename, size)
182
+
183
+ save_png(master, LINUX_ICON_DIR / "app_icon.png", 256)
184
+
185
+ master_for_ico = master.resize((256, 256), Image.Resampling.LANCZOS)
186
+ master_for_ico.save(
187
+ WINDOWS_ICON_PATH,
188
+ format="ICO",
189
+ sizes=[(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)],
190
+ )
191
+
192
+ web_icon_sizes = {
193
+ 192: "Icon-192.png",
194
+ 512: "Icon-512.png",
195
+ }
196
+ for size, filename in web_icon_sizes.items():
197
+ copy_png(master, WEB_ICONS_DIR / filename, size)
198
+ copy_png(master, WEB_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-"), size)
199
+ copy_png(master, SERVER_PUBLIC_ICONS_DIR / filename, size)
200
+ copy_png(master, SERVER_PUBLIC_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-"), size)
201
+
202
+ copy_png(master, WEB_DIR / "favicon.png", 32)
203
+ copy_png(master, SERVER_PUBLIC_DIR / "favicon.png", 32)
204
+ write_favicon_svg(WEB_DIR / "favicon.svg")
205
+ write_favicon_svg(SERVER_PUBLIC_DIR / "favicon.svg")
206
+
207
+ android_icon_sizes = {
208
+ "mipmap-mdpi": 48,
209
+ "mipmap-hdpi": 72,
210
+ "mipmap-xhdpi": 96,
211
+ "mipmap-xxhdpi": 144,
212
+ "mipmap-xxxhdpi": 192,
213
+ }
214
+ for folder, size in android_icon_sizes.items():
215
+ copy_png(master, ANDROID_RES_DIR / folder / "ic_launcher.png", size)
216
+
217
+
218
+ if __name__ == "__main__":
219
+ main()
Binary file
@@ -0,0 +1,12 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" stop-color="#8f6d3e"/>
5
+ <stop offset="100%" stop-color="#2f7d6e"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <rect x="2.5" y="2.5" width="27" height="27" rx="9" ry="9" fill="url(#bg)" stroke="#ffffff" stroke-opacity="0.16" stroke-width="1"/>
9
+ <polygon points="16,5.7 5.2,11.6 16,17.6 26.8,11.6" fill="white"/>
10
+ <polyline points="5.2,17.6 16,23.5 26.8,17.6" fill="none" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
11
+ <polyline points="5.2,22.7 16,28.1 26.8,22.7" fill="none" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
12
+ </svg>
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <!--
5
+ If you are serving your web app in a path other than the root, change the
6
+ href value below to reflect the base path you are serving from.
7
+
8
+ The path provided below has to start and end with a slash "/" in order for
9
+ it to work correctly.
10
+
11
+ For more details:
12
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
13
+
14
+ This is a placeholder for base href that will be replaced by the value of
15
+ the `--base-href` argument provided to `flutter build`.
16
+ -->
17
+ <base href="$FLUTTER_BASE_HREF">
18
+
19
+ <meta charset="UTF-8">
20
+ <meta content="IE=Edge" http-equiv="X-UA-Compatible">
21
+ <meta name="description" content="NeoAgent Flutter client for web and Android.">
22
+
23
+ <!-- iOS meta tags & icons -->
24
+ <meta name="mobile-web-app-capable" content="yes">
25
+ <meta name="apple-mobile-web-app-status-bar-style" content="black">
26
+ <meta name="apple-mobile-web-app-title" content="NeoAgent">
27
+ <link rel="apple-touch-icon" href="icons/Icon-192.png">
28
+
29
+ <!-- Favicon -->
30
+ <link rel="icon" type="image/svg+xml" href="favicon.svg"/>
31
+ <link rel="icon" type="image/png" href="favicon.png"/>
32
+
33
+ <title>NeoAgent</title>
34
+ <link rel="manifest" href="manifest.json">
35
+ </head>
36
+ <body>
37
+ <script src="flutter_bootstrap.js" async></script>
38
+ </body>
39
+ </html>