├── .github
├── FUNDING.yml
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── CNAME
├── LICENSE
├── README.md
├── WallPanelApp
├── .gitignore
├── build.gradle
├── lint.xml
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── xyz
│ │ └── wallpanel
│ │ └── app
│ │ └── BrowserActivityNativeTest.kt
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ ├── error_page.html
│ ├── icon.png
│ └── styles.css
│ ├── java
│ ├── com
│ │ └── jjoe64
│ │ │ └── motiondetection
│ │ │ └── motiondetection
│ │ │ ├── AggregateLumaMotionDetection.java
│ │ │ ├── Comparer.java
│ │ │ ├── IMotionDetection.java
│ │ │ ├── ImageProcessing.java
│ │ │ ├── MotionDetector.java
│ │ │ ├── MotionDetectorCallback.java
│ │ │ └── State.java
│ └── xyz
│ │ └── wallpanel
│ │ └── app
│ │ ├── AppExceptionHandler.kt
│ │ ├── BootUpReceiver.kt
│ │ ├── WallPanel.kt
│ │ ├── di
│ │ ├── ActivityModule.java
│ │ ├── ActivityScope.java
│ │ ├── AndroidBindingModule.kt
│ │ ├── ApplicationComponent.java
│ │ ├── ApplicationModule.java
│ │ ├── ApplicationScope.java
│ │ ├── DaggerViewModelFactory.kt
│ │ ├── DaggerViewModelInjectionModule.kt
│ │ ├── ServiceSubcomponent.java
│ │ ├── ServicesModule.java
│ │ └── ViewModelKey.kt
│ │ ├── ext
│ │ ├── ArrayExt.kt
│ │ └── StringExt.kt
│ │ ├── modules
│ │ ├── CameraCallback.java
│ │ ├── CameraReader.kt
│ │ ├── MQTTModule.kt
│ │ ├── Motion.kt
│ │ ├── MotionDetector.kt
│ │ ├── SensorCallback.kt
│ │ ├── SensorReader.kt
│ │ ├── Stream.kt
│ │ ├── StreamingDetector.kt
│ │ └── TextToSpeechModule.kt
│ │ ├── network
│ │ ├── ConnectionLiveData.kt
│ │ ├── IMqttManagerListener.kt
│ │ ├── MQTT3Service.kt
│ │ ├── MQTT5Service.kt
│ │ ├── MQTTOptions.kt
│ │ ├── MQTTServiceInterface.kt
│ │ └── WallPanelService.kt
│ │ ├── persistence
│ │ └── Configuration.kt
│ │ ├── ui
│ │ ├── DetectionViewModel.kt
│ │ ├── activities
│ │ │ ├── BaseBrowserActivity.kt
│ │ │ ├── BrowserActivityNative.kt
│ │ │ ├── LiveCameraActivity.kt
│ │ │ ├── SettingsActivity.kt
│ │ │ └── TestActivity.kt
│ │ ├── fragments
│ │ │ ├── AboutFragment.kt
│ │ │ ├── BaseSettingsFragment.kt
│ │ │ ├── CameraSettingsFragment.kt
│ │ │ ├── CodeBottomSheetFragment.kt
│ │ │ ├── FaceSettingsFragment.kt
│ │ │ ├── HttpSettingsFragment.kt
│ │ │ ├── MotionSettingsFragment.kt
│ │ │ ├── MqttSettingsFragment.kt
│ │ │ ├── QrCodeSettingsFragment.kt
│ │ │ ├── SensorsSettingsFragment.kt
│ │ │ └── SettingsFragment.kt
│ │ └── views
│ │ │ ├── BaseView.kt
│ │ │ ├── CameraSourcePreview.kt
│ │ │ ├── CustomWebView.kt
│ │ │ ├── ScreenSaverView.kt
│ │ │ ├── SettingsCodeView.kt
│ │ │ └── WebClientCallback.kt
│ │ └── utils
│ │ ├── BrowserUtils.kt
│ │ ├── CameraUtils.kt
│ │ ├── CrashlyticsDebugTree.kt
│ │ ├── CrashlyticsTree.java
│ │ ├── DateUtils.kt
│ │ ├── DialogUtils.kt
│ │ ├── InternalWebChromeClient.kt
│ │ ├── InternalWebClient.kt
│ │ ├── LauncherShortcuts.kt
│ │ ├── MqttUtils.kt
│ │ ├── NotificationUtils.java
│ │ ├── ScreenUtils.kt
│ │ ├── StringUtils.java
│ │ ├── WallpanelDebugTree.kt
│ │ └── WebClientRenderWrapper.kt
│ └── res
│ ├── drawable-anydpi-v24
│ └── ic_stat_name.xml
│ ├── drawable-hdpi
│ └── ic_stat_name.png
│ ├── drawable-mdpi
│ └── ic_stat_name.png
│ ├── drawable-xhdpi
│ └── ic_stat_name.png
│ ├── drawable-xxhdpi
│ └── ic_stat_name.png
│ ├── drawable
│ ├── button_blue.xml
│ ├── button_blue_pressed.xml
│ ├── button_blue_selector.xml
│ ├── button_border.xml
│ ├── button_border_bottom.xml
│ ├── button_border_bottom_corner.xml
│ ├── button_border_bottom_corner_white.xml
│ ├── button_border_bottom_white.xml
│ ├── button_border_left.xml
│ ├── button_border_left_white.xml
│ ├── button_border_top_corner.xml
│ ├── button_border_top_corner_white.xml
│ ├── button_disabled.xml
│ ├── button_green.xml
│ ├── button_green_pressed.xml
│ ├── button_green_selector.xml
│ ├── ic_baseline_backspace.xml
│ ├── ic_baseline_close.xml
│ ├── ic_baseline_help.xml
│ ├── ic_baseline_lock.xml
│ ├── ic_baseline_lock_open.xml
│ ├── ic_baseline_refresh.xml
│ ├── ic_baseline_videocam.xml
│ ├── ic_cloud.xml
│ ├── ic_dashboard.xml
│ ├── ic_dashboard_white.xml
│ ├── ic_directions_run.xml
│ ├── ic_email_black.xml
│ ├── ic_face.xml
│ ├── ic_file_edit.xml
│ ├── ic_github_blk.xml
│ ├── ic_help.xml
│ ├── ic_help_black.xml
│ ├── ic_mister.xml
│ ├── ic_photo_camera.xml
│ ├── ic_qr_code.xml
│ ├── ic_radio_button_checked_black.xml
│ ├── ic_radio_button_unchecked_black.xml
│ ├── ic_sensor.xml
│ ├── ic_settings_brightness.xml
│ ├── ic_settings_cyan.xml
│ ├── ic_social_reddit.xml
│ ├── ic_star_black.xml
│ └── logo_front.xml
│ ├── layout-land
│ ├── dialog_screen_saver.xml
│ └── fragment_code_bottom_sheet.xml
│ ├── layout-sw600dp-land
│ ├── dialog_screen_saver.xml
│ └── fragment_code_bottom_sheet.xml
│ ├── layout-sw600dp
│ ├── dialog_screen_saver.xml
│ └── fragment_code_bottom_sheet.xml
│ ├── layout-sw720dp-land
│ ├── dialog_screen_saver.xml
│ └── fragment_code_bottom_sheet.xml
│ ├── layout-sw720dp
│ ├── dialog_screen_saver.xml
│ └── fragment_code_bottom_sheet.xml
│ ├── layout
│ ├── activity_browser.xml
│ ├── activity_live_camera.xml
│ ├── activity_settings.xml
│ ├── activity_test.xml
│ ├── activity_welcome.xml
│ ├── dialog_code_set.xml
│ ├── dialog_screen_saver.xml
│ ├── fragment_about.xml
│ ├── fragment_code_bottom_sheet.xml
│ └── view_keypad.xml
│ ├── menu
│ ├── menu_dashboard.xml
│ └── menu_help.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_background.png
│ ├── ic_launcher_foreground.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_background.png
│ ├── ic_launcher_foreground.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_foreground.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_foreground.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_foreground.png
│ └── ic_launcher_round.png
│ ├── navigation
│ └── settings_nav_graph.xml
│ ├── values-night
│ ├── colors.xml
│ └── styles.xml
│ ├── values
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── donottranslate.xml
│ ├── ic_launcher_background.xml
│ ├── strings.xml
│ └── styles.xml
│ ├── web_hi_res_512.png
│ └── xml
│ ├── network_config.xml
│ ├── pref_camera.xml
│ ├── pref_face.xml
│ ├── pref_general.xml
│ ├── pref_http.xml
│ ├── pref_motion.xml
│ ├── pref_mqtt.xml
│ ├── pref_qrcode.xml
│ └── pref_sensors.xml
├── _config.yml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── img
├── dashboard1.png
├── dashboard2.png
├── dashboard3.png
└── logo.png
├── settings.gradle
└── website
├── .gitignore
├── .prettierrc
├── README.md
├── babel.config.js
├── docs
├── getting-started.md
├── launch-external-apps.md
├── limitations.md
├── remote-control
│ ├── _category_.json
│ ├── commands.md
│ ├── mqtt-setup.md
│ └── sensors.md
├── screensaver.md
└── video-streaming.md
├── docusaurus.config.js
├── package-lock.json
├── package.json
├── sidebars.js
├── src
├── components
│ └── HomepageFeatures
│ │ ├── index.tsx
│ │ └── styles.module.css
├── css
│ └── custom.css
└── pages
│ ├── index.module.css
│ ├── index.tsx
│ └── privacy-policy.md
├── static
├── .nojekyll
└── img
│ ├── favicon.ico
│ ├── logo.png
│ ├── mqtt.png
│ ├── mqtt_client.png
│ ├── mqtt_discovery.png
│ ├── settings_button.png
│ ├── settings_button_options.png
│ ├── settings_code.png
│ └── settings_dashboard.png
├── tsconfig.json
└── yarn.lock
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: ["TheTimeWalker"]
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Report
3 | about: Report an issue
4 | title: '[BUG]'
5 |
6 | ---
7 |
8 | **Describe the bug**
9 | A clear and concise description of what the bug is.
10 |
11 | **To Reproduce**
12 | Steps to reproduce the behavior:
13 |
14 |
15 | **Smartphone (please complete the following information):**
16 | - Device: [e.g. Samsun, Android, Fire Tablet]
17 | - OS: [e.g. Android 21, Oreo, Fire OS 7]
18 | - Applicaiton version [app > settings > version]
19 |
20 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[FEATURE]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Your feature request. Please describe.**
11 | What is the feature, why is it valuable to the community or application?
12 |
13 | **NOTE**
14 | We get many feature requests, each feature requires community support and also development time. Features that have no community support are not considered. If you are not contributing to the feature, then the feature may not happen.
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # IntelliJ
2 | *.iml
3 | .idea/
4 | misc.xml
5 | deploymentTargetDropDown.xml
6 | render.experimental.xml
7 |
8 | # Gradle
9 | .gradle/
10 | build/
11 |
12 | # Local configuration file (sdk path, etc)
13 | local.properties
14 | reports
15 |
16 | # Apple
17 | .DS_Store
18 | npm-debug.log
19 |
20 | #Fabric
21 | crashlytics.properties
22 | fabric.properties
23 |
24 | # Log/OS Files
25 | *.log
26 |
27 | # Android Studio generated files and folders
28 | captures/
29 | .externalNativeBuild/
30 | .cxx/
31 | *.apk
32 | output.json
33 |
34 | # Keystore files
35 | *.jks
36 | *.keystore
37 |
38 | # Google Services (e.g. APIs or Firebase)
39 | google-services.json
40 |
41 | # Android Profiling
42 | *.hprof
43 | keystore.gradle
44 |
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | wallpanel.xyz
--------------------------------------------------------------------------------
/WallPanelApp/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # IntelliJ IDEA
3 | .idea
4 | *.iml
5 | app.iml
6 | /build
7 |
8 | # Gradle
9 | .gradle
10 | gradlew.bat
11 | build
12 | local.properties
13 | reports
14 |
15 | # Apple
16 | .DS_Store
17 | npm-debug.log
18 |
19 | #Fabric
20 | crashlytics.properties
21 |
22 | # Keystore files
23 | # Uncomment the following lines if you do not want to check your keystore files in.
24 | /keystore
25 | *.jks
26 | *.keystore
27 | keystore.gradle
28 |
--------------------------------------------------------------------------------
/WallPanelApp/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/WallPanelApp/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\raimund\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | -keepclassmembernames class io.netty.** { *; }
20 | -keepclassmembers class org.jctools.** { *; }
--------------------------------------------------------------------------------
/WallPanelApp/src/androidTest/java/xyz/wallpanel/app/BrowserActivityNativeTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Wallpanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app
18 |
19 | import xyz.wallpanel.app.utils.BrowserUtils
20 | import junit.framework.TestCase
21 |
22 | import org.junit.After
23 | import org.junit.Before
24 | import org.junit.Test
25 |
26 | class BrowserActivityNativeTest : TestCase() {
27 |
28 | @Before
29 | public override fun setUp() {
30 | }
31 |
32 | @After
33 | public override fun tearDown() {
34 | }
35 |
36 | @Test
37 | fun testParseIntentMethod() {
38 | val browserUtils = BrowserUtils()
39 | var intent = browserUtils.parseIntent("intent:#Intent;launchFlags=0x10000000;component=com.google.android.apps.maps/com.google.android.maps.MapsActivity;end")
40 | assertNotNull(intent)
41 | assertEquals("com.google.android.maps.MapsActivity", intent?.component?.className)
42 | assertEquals("com.google.android.apps.maps", intent?.component?.packageName)
43 | assertEquals("android.intent.action.VIEW", intent?.action)
44 |
45 | intent = browserUtils.parseIntent("intent:#Intent;launchFlags=0x10000000;component=com.amazon.avod/.client.activity.HomeScreenActivity;end")
46 | assertNotNull(intent)
47 | assertEquals(".client.activity.HomeScreenActivity", intent?.component?.className)
48 | assertEquals("com.amazon.avod", intent?.component?.packageName)
49 | assertEquals("android.intent.action.VIEW", intent?.action)
50 | }
51 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/assets/error_page.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Connection Error
28 | This page will automatically reload when connected.
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/assets/icon.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/assets/styles.css:
--------------------------------------------------------------------------------
1 | html { box-sizing: border-box; }
2 |
3 | *,
4 | *::before,
5 | *::after { box-sizing: inherit; }
6 |
7 | body * {
8 | margin: 0;
9 | padding: 0;
10 | }
11 |
12 | body {
13 | font: normal 100%/1.15 "Merriweather", serif;
14 | background-color: #ffffff;
15 | color: #fff;
16 | }
17 |
18 | .wrapper {
19 | position: relative;
20 | max-width: 1298px;
21 | height: auto;
22 | margin: 1em auto 0 auto;
23 | }
24 |
25 | /* https://www.flaticon.com/authors/vectors-market */
26 | /* https://www.flaticon.com/authors/icomoon */
27 | .box {
28 | max-width: 70%;
29 | min-height: auto;
30 | margin: 0 auto;
31 | padding: 2em 0em;
32 | text-align: center;
33 | }
34 |
35 | h1, p:not(:last-of-type) { }
36 |
37 | h1 {
38 | margin: 0 0 1rem 0;
39 | font-size: 2em;
40 | color: #216f79;
41 | }
42 |
43 | p {
44 | margin-top: 0.5em;
45 | margin-bottom: 0.5em;
46 | font-size: 1.5em;
47 | text-align: center;
48 | color: #216f79;
49 | }
50 |
51 | p:first-of-type { margin-top: 0em; }
52 |
53 | p > a {
54 | border-bottom: 1px dashed #216f79;
55 | font-style: italic;
56 | text-decoration: none;
57 | color: #216f79;
58 | }
59 |
60 | p > a:hover { text-shadow: 0 0 6px #216f79; }
61 |
62 | p img { vertical-align: bottom; }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/com/jjoe64/motiondetection/motiondetection/IMotionDetection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.jjoe64.motiondetection.motiondetection;
18 |
19 | public interface IMotionDetection {
20 |
21 | /**
22 | * Get the previous image in integer array format
23 | *
24 | * @return int array of previous image.
25 | */
26 | public int[] getPrevious();
27 |
28 | /**
29 | * Detect motion.
30 | *
31 | * @param data
32 | * integer array representing an image.
33 | * @param width
34 | * Width of the image.
35 | * @param height
36 | * Height of the image.
37 | * @return boolean True is there is motion.
38 | * @throws NullPointerException
39 | * if data integer array is NULL.
40 | */
41 | public boolean detect(int[] data, int width, int height);
42 | }
43 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/com/jjoe64/motiondetection/motiondetection/MotionDetectorCallback.java:
--------------------------------------------------------------------------------
1 | package com.jjoe64.motiondetection.motiondetection;
2 |
3 | public interface MotionDetectorCallback {
4 | void onMotionDetected();
5 | void onTooDark();
6 | }
7 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/com/jjoe64/motiondetection/motiondetection/State.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.jjoe64.motiondetection.motiondetection;
18 |
19 | public class State {
20 |
21 | private int[] map = null;
22 | private int width;
23 | private int height;
24 | private int average;
25 |
26 | public State(int[] data, int width, int height) {
27 | if (data == null) throw new NullPointerException();
28 |
29 | this.map = data.clone();
30 | this.width = width;
31 | this.height = height;
32 |
33 | // build map and stats
34 | this.average = 0;
35 | for (int y = 0, xy = 0; y < this.height; y++) {
36 | for (int x = 0; x < this.width; x++, xy++) {
37 | this.average += data[xy];
38 | }
39 | }
40 | this.average = (this.average / (this.width * this.height));
41 | }
42 |
43 | /**
44 | * Get Map of the State.
45 | *
46 | * @return integer array of the State.
47 | */
48 | public int[] getMap() {
49 | return map;
50 | }
51 |
52 | /**
53 | * Get the width of the State.
54 | *
55 | * @return integer representing the width of the state.
56 | */
57 | public int getWidth() {
58 | return width;
59 | }
60 |
61 | /**
62 | * Get the height of the State.
63 | *
64 | * @return integer representing the height of the state.
65 | */
66 | public int getHeight() {
67 | return height;
68 | }
69 |
70 | /**
71 | * {@inheritDoc}
72 | */
73 | @Override
74 | public String toString() {
75 | StringBuilder output = new StringBuilder();
76 | output.append("h=" + height + " w=" + width + "\n");
77 | for (int y = 0, xy = 0; y < height; y++) {
78 | output.append('|');
79 | for (int x = 0; x < width; x++, xy++) {
80 | output.append(map[xy]);
81 | output.append('|');
82 | }
83 | output.append("\n");
84 | }
85 | return output.toString();
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/AppExceptionHandler.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Wallpanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app
18 |
19 | import android.app.Activity
20 | import android.app.AlarmManager
21 | import android.app.PendingIntent
22 | import android.content.Context
23 | import android.content.Intent
24 | import xyz.wallpanel.app.ui.activities.BrowserActivityNative
25 | import kotlin.system.exitProcess
26 |
27 | class AppExceptionHandler(private val activity: Activity) : Thread.UncaughtExceptionHandler {
28 | override fun uncaughtException(thread: Thread, ex: Throwable) {
29 | val intent = Intent(activity, BrowserActivityNative::class.java)
30 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
31 | or Intent.FLAG_ACTIVITY_CLEAR_TASK
32 | or Intent.FLAG_ACTIVITY_NEW_TASK)
33 | val pendingIntent = PendingIntent.getActivity(activity.applicationContext, 0, intent, PendingIntent.FLAG_ONE_SHOT)
34 | val mgr = activity.applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
35 | mgr[AlarmManager.RTC, System.currentTimeMillis() + 1000] = pendingIntent
36 | activity.finish()
37 | exitProcess(2)
38 | }
39 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/BootUpReceiver.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app
18 |
19 | import android.content.BroadcastReceiver
20 | import android.content.Context
21 | import android.content.Intent
22 | import androidx.preference.PreferenceManager
23 | import xyz.wallpanel.app.R
24 | import xyz.wallpanel.app.ui.activities.BrowserActivityNative
25 |
26 | class BootUpReceiver : BroadcastReceiver() {
27 |
28 | override fun onReceive(context: Context, intent: Intent) {
29 | if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) {
30 | val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.applicationContext)
31 | val startOnBoot = sharedPreferences.getBoolean(context.getString(R.string.key_setting_android_startonboot), false)
32 | if (startOnBoot) {
33 | val i = Intent(context, BrowserActivityNative::class.java)
34 | i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
35 | context.startActivity(i)
36 | }
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/ActivityModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di;
18 |
19 | import android.app.Application;
20 | import android.content.Context;
21 | import android.content.SharedPreferences;
22 |
23 | import android.content.res.Resources;
24 | import android.location.LocationManager;
25 | import androidx.preference.PreferenceManager;
26 | import android.view.LayoutInflater;
27 |
28 | import xyz.wallpanel.app.modules.CameraReader;
29 | import xyz.wallpanel.app.modules.SensorReader;
30 | import xyz.wallpanel.app.network.MQTTOptions;
31 | import xyz.wallpanel.app.persistence.Configuration;
32 | import xyz.wallpanel.app.utils.DialogUtils;
33 | import xyz.wallpanel.app.utils.ScreenUtils;
34 |
35 | import javax.inject.Singleton;
36 |
37 | import dagger.Module;
38 | import dagger.Provides;
39 |
40 | @Module
41 | class ActivityModule {
42 |
43 | @Provides
44 | static DialogUtils providesDialogUtils(Application application) {
45 | return new DialogUtils(application);
46 | }
47 |
48 | @Provides
49 | static Resources providesResources(Application application) {
50 | return application.getResources();
51 | }
52 |
53 | @Provides
54 | static LayoutInflater providesInflater(Application application) {
55 | return (LayoutInflater) application.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
56 | }
57 |
58 | @Provides
59 | static LocationManager provideLocationManager(Application application) {
60 | return (LocationManager) application.getSystemService(Context.LOCATION_SERVICE);
61 | }
62 |
63 | @Provides
64 | @Singleton
65 | SharedPreferences provideSharedPreferences(Application app) {
66 | return PreferenceManager.getDefaultSharedPreferences(app.getApplicationContext());
67 | }
68 |
69 | @Provides
70 | static Configuration provideConfiguration(Application app, SharedPreferences sharedPreferences) {
71 | return new Configuration(app, sharedPreferences);
72 | }
73 |
74 | @Provides
75 | static CameraReader provideCameraReader(Application app) {
76 | return new CameraReader(app);
77 | }
78 |
79 | @Provides
80 | static SensorReader provideSensorReader(Application app) {
81 | return new SensorReader(app);
82 | }
83 |
84 | @Provides
85 | static MQTTOptions provideMQTTOptions(Configuration configuration) {
86 | return new MQTTOptions(configuration);
87 | }
88 |
89 | @Provides
90 | static ScreenUtils screenUtils(Application application, Configuration configuration) {
91 | return new ScreenUtils(application, configuration);
92 | }
93 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/ActivityScope.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di;
18 |
19 | import java.lang.annotation.Documented;
20 | import java.lang.annotation.Retention;
21 |
22 | import javax.inject.Scope;
23 |
24 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
25 |
26 | @Scope
27 | @Documented
28 | @Retention(RUNTIME)
29 | public @interface ActivityScope {
30 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/AndroidBindingModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di
18 |
19 | import androidx.lifecycle.ViewModel
20 | import xyz.wallpanel.app.BootUpReceiver
21 | import xyz.wallpanel.app.network.WallPanelService
22 | import xyz.wallpanel.app.ui.*
23 | import xyz.wallpanel.app.ui.activities.*
24 | import xyz.wallpanel.app.ui.fragments.*
25 | import dagger.Binds
26 | import dagger.Module
27 | import dagger.android.ContributesAndroidInjector
28 | import dagger.multibindings.IntoMap
29 |
30 | @Module
31 | internal abstract class AndroidBindingModule {
32 |
33 | @Binds
34 | @IntoMap
35 | @ViewModelKey(DetectionViewModel::class)
36 | abstract fun cameraViewModel(viewModel: DetectionViewModel): ViewModel
37 |
38 | @ContributesAndroidInjector
39 | internal abstract fun alarmService(): WallPanelService
40 |
41 | @ContributesAndroidInjector
42 | internal abstract fun settingsActivity(): SettingsActivity
43 |
44 | @ContributesAndroidInjector
45 | internal abstract fun browserActivity(): BaseBrowserActivity
46 |
47 | @ContributesAndroidInjector
48 | internal abstract fun browserActivityNative(): BrowserActivityNative
49 |
50 | @ContributesAndroidInjector
51 | internal abstract fun liveCameraActivity(): LiveCameraActivity
52 |
53 | @ContributesAndroidInjector
54 | internal abstract fun bootupReceiver(): BootUpReceiver
55 |
56 | @ContributesAndroidInjector
57 | internal abstract fun baseSettingsFragment(): BaseSettingsFragment
58 |
59 | @ContributesAndroidInjector
60 | internal abstract fun settingsFragment(): SettingsFragment
61 |
62 | @ContributesAndroidInjector
63 | internal abstract fun cameraSettings(): CameraSettingsFragment
64 |
65 | @ContributesAndroidInjector
66 | internal abstract fun mqttSettings(): MqttSettingsFragment
67 |
68 | @ContributesAndroidInjector
69 | internal abstract fun httpSettings(): HttpSettingsFragment
70 |
71 | @ContributesAndroidInjector
72 | internal abstract fun motionSettings(): MotionSettingsFragment
73 |
74 | @ContributesAndroidInjector
75 | internal abstract fun faceSettings(): FaceSettingsFragment
76 |
77 | @ContributesAndroidInjector
78 | internal abstract fun qrCodeSettings(): QrCodeSettingsFragment
79 |
80 | @ContributesAndroidInjector
81 | internal abstract fun sensorsSettings(): SensorsSettingsFragment
82 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/ApplicationComponent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di;
18 |
19 | import xyz.wallpanel.app.WallPanel;
20 |
21 | import javax.inject.Singleton;
22 |
23 | import dagger.Component;
24 | import dagger.android.AndroidInjector;
25 | import dagger.android.support.AndroidSupportInjectionModule;
26 |
27 | @Singleton
28 | @Component(modules = {
29 | AndroidSupportInjectionModule.class,
30 | ApplicationModule.class,
31 | ActivityModule.class,
32 | AndroidBindingModule.class,
33 | DaggerViewModelInjectionModule.class
34 | })
35 |
36 | @ApplicationScope
37 | public interface ApplicationComponent extends AndroidInjector {
38 | @Component.Builder
39 | abstract class Builder extends AndroidInjector.Builder{
40 | }
41 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/ApplicationModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di;
18 |
19 | import android.app.Application;
20 | import android.content.Context;
21 |
22 | import xyz.wallpanel.app.WallPanel;
23 |
24 | import javax.inject.Singleton;
25 |
26 | import dagger.Binds;
27 | import dagger.Module;
28 | import dagger.Provides;
29 |
30 | @Module
31 | abstract class ApplicationModule {
32 |
33 | @Binds
34 | abstract Application application(WallPanel baseApplication);
35 |
36 | @Provides
37 | @Singleton
38 | static Context provideContext(Application application) {
39 | return application;
40 | }
41 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/ApplicationScope.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di;
18 |
19 | import java.lang.annotation.Documented;
20 | import java.lang.annotation.Retention;
21 |
22 | import javax.inject.Scope;
23 |
24 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
25 |
26 | @Scope
27 | @Documented
28 | @Retention(RUNTIME)
29 | public @interface ApplicationScope {
30 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/DaggerViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di
18 |
19 | import androidx.lifecycle.ViewModel
20 | import androidx.lifecycle.ViewModelProvider
21 | import javax.inject.Inject
22 | import javax.inject.Provider
23 | import javax.inject.Singleton
24 |
25 | @Suppress("UNCHECKED_CAST")
26 | @Singleton
27 | class DaggerViewModelFactory
28 | @Inject constructor(
29 | private val creators: Map, @JvmSuppressWildcards Provider>) : ViewModelProvider.Factory {
30 |
31 | override fun create(modelClass: Class): T {
32 | val creator = creators[modelClass] ?:
33 | creators.asIterable().firstOrNull { modelClass.isAssignableFrom(it.key) }?.value
34 | ?: throw IllegalArgumentException("unknown model class " + modelClass)
35 |
36 | return try {
37 | creator.get() as T
38 | } catch (e: Exception) {
39 | throw RuntimeException(e)
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/DaggerViewModelInjectionModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di
18 |
19 | import androidx.lifecycle.ViewModelProvider
20 | import dagger.Binds
21 | import dagger.Module
22 |
23 | @Module
24 | abstract class DaggerViewModelInjectionModule {
25 | @Binds
26 | internal abstract fun bindViewModelFactory(factory: DaggerViewModelFactory): ViewModelProvider.Factory
27 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/ServiceSubcomponent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di;
18 |
19 | import xyz.wallpanel.app.network.WallPanelService;
20 |
21 | import dagger.Subcomponent;
22 | import dagger.android.AndroidInjector;
23 |
24 | @Subcomponent(modules = {})
25 | public interface ServiceSubcomponent extends AndroidInjector {
26 | @Subcomponent.Builder
27 | abstract class Builder extends AndroidInjector.Builder {
28 | }
29 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/ServicesModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di;
18 |
19 | import xyz.wallpanel.app.network.WallPanelService;
20 |
21 | import dagger.Module;
22 | import dagger.android.ContributesAndroidInjector;
23 |
24 | @Module
25 | abstract class ServicesModule {
26 |
27 | @ContributesAndroidInjector
28 | abstract WallPanelService contributeMyService();
29 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/di/ViewModelKey.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.di
18 |
19 | import androidx.lifecycle.ViewModel
20 | import dagger.MapKey
21 | import kotlin.reflect.KClass
22 |
23 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
24 | @MapKey
25 | annotation class ViewModelKey(val value: KClass)
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/ext/ArrayExt.kt:
--------------------------------------------------------------------------------
1 | package xyz.wallpanel.app.ext
2 |
3 | fun Array.convertArrayToString(): String {
4 | val strSeparator = ","
5 | val str = StringBuilder()
6 | for (i in this.indices) {
7 | str.append(this[i])
8 | // Do not append comma at the end of last element
9 | if (i < this.size - 1) {
10 | str.append(strSeparator)
11 | }
12 | }
13 | return str.toString()
14 | }
15 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/ext/StringExt.kt:
--------------------------------------------------------------------------------
1 | package xyz.wallpanel.app.ext
2 |
3 |
4 | fun String.convertStringToArray(str: String): Array {
5 | val strSeparator = ","
6 | return str.split(strSeparator).toTypedArray()
7 | }
8 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/modules/CameraCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.modules;
18 |
19 | public interface CameraCallback {
20 | void onMotionDetected();
21 | void onTooDark();
22 | void onFaceDetected();
23 | void onQRCode(String data);
24 | void onCameraError();
25 | void onDetectorError();
26 | }
27 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/modules/Motion.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.modules
18 |
19 | /**
20 | * Created by Michael Ritchie on 7/6/18.
21 | */
22 | class Motion {
23 |
24 | var type = MOTION_NOT_DETECTED
25 | var byteArray: ByteArray? = null
26 | var width: Int? = null
27 | var height: Int? = null
28 |
29 | companion object {
30 | val MOTION_TOO_DARK = "motion_too_dark"
31 | val MOTION_DETECTED = "motion_detected"
32 | val MOTION_NOT_DETECTED = "motion_not_detected"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/modules/SensorCallback.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.modules
18 |
19 | import org.json.JSONObject
20 |
21 | interface SensorCallback {
22 | fun publishSensorData(sensorName: String, sensorData: JSONObject)
23 | }
24 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/modules/Stream.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.modules
18 |
19 | /**
20 | * Created by Michael Ritchie on 7/6/18.
21 | */
22 | class Stream {
23 | var byteArray: ByteArray? = null
24 | var width: Int? = null
25 | var height: Int? = null
26 | companion object {
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/modules/StreamingDetector.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.modules
18 |
19 | import android.util.SparseArray
20 |
21 | import com.google.android.gms.vision.Detector
22 | import com.google.android.gms.vision.Frame
23 |
24 | /**
25 | * Created by Michael Ritchie on 7/6/18.
26 | */
27 | class StreamingDetector private constructor() : Detector() {
28 | init {
29 | }
30 | override fun detect(frame: Frame?): SparseArray {
31 | if (frame == null) {
32 | throw IllegalArgumentException("No frame supplied.")
33 | } else {
34 | val sparseArray = SparseArray()
35 | val byteBuffer = frame.grayscaleImageData
36 | val bytes = byteBuffer.array()
37 | val w = frame.metadata.width
38 | val h = frame.metadata.height
39 | val stream = Stream()
40 | stream.byteArray = bytes
41 | stream.width = w
42 | stream.height = h
43 | sparseArray.put(0, stream)
44 | return sparseArray
45 | }
46 | }
47 | class Builder() {
48 | fun build(): StreamingDetector {
49 | return StreamingDetector()
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/network/ConnectionLiveData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.network
18 |
19 | import androidx.lifecycle.MutableLiveData
20 | import android.content.BroadcastReceiver
21 | import android.content.Context
22 | import android.content.Intent
23 | import android.content.IntentFilter
24 | import android.net.ConnectivityManager
25 |
26 | import timber.log.Timber
27 | import java.util.concurrent.atomic.AtomicBoolean
28 |
29 | class ConnectionLiveData(private val context: Context) : MutableLiveData() {
30 |
31 | private var connCallbackListener: ConnCallbackListener? = null
32 |
33 | init {
34 | connCallbackListener = object : ConnCallbackListener {
35 | override fun networkConnect() {
36 | value = true
37 | }
38 | override fun networkDisconnect() {
39 | value = false
40 | }
41 | }
42 | }
43 |
44 | override fun onActive() {
45 | super.onActive()
46 | context.registerReceiver(connectionReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
47 | }
48 |
49 | override fun onInactive() {
50 | super.onInactive()
51 | context.unregisterReceiver(connectionReceiver)
52 | }
53 |
54 | private val connectionReceiver = object : BroadcastReceiver() {
55 | override fun onReceive(context: Context, intent: Intent) {
56 | val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
57 | val currentNetworkInfo = connectivityManager.activeNetworkInfo
58 | if (currentNetworkInfo != null && currentNetworkInfo.isConnected) {
59 | Timber.d("Network Connected")
60 | hasNetwork.set(true)
61 | value = true
62 | } else if (hasNetwork.get()) {
63 | Timber.d("Network Disconnected")
64 | hasNetwork.set(false)
65 | value = false
66 | }
67 | }
68 | }
69 |
70 | interface ConnCallbackListener {
71 | fun networkConnect()
72 | fun networkDisconnect()
73 | }
74 |
75 | companion object {
76 | var hasNetwork = AtomicBoolean(true)
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/network/IMqttManagerListener.kt:
--------------------------------------------------------------------------------
1 | package xyz.wallpanel.app.network
2 |
3 | interface IMqttManagerListener {
4 | fun subscriptionMessage(id: String, topic: String, payload: String)
5 | fun handleMqttException(errorMessage: String)
6 | fun handleMqttDisconnected()
7 | fun handleMqttConnected()
8 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/network/MQTTServiceInterface.kt:
--------------------------------------------------------------------------------
1 | package xyz.wallpanel.app.network
2 |
3 | import android.content.Context
4 | import com.hivemq.client.mqtt.mqtt5.exceptions.Mqtt5MessageException
5 |
6 | interface MQTTServiceInterface {
7 | val isReady: Boolean
8 |
9 | fun publish(topic: String, payload: String, retain: Boolean)
10 | fun reconfigure(context: Context, options: MQTTOptions, listener: IMqttManagerListener)
11 |
12 | @Throws(Mqtt5MessageException::class)
13 | fun close()
14 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/ui/activities/SettingsActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.ui.activities
18 |
19 |
20 | import android.content.Context
21 | import android.content.Intent
22 | import android.os.Bundle
23 | import android.view.MenuItem
24 | import xyz.wallpanel.app.R
25 | import xyz.wallpanel.app.persistence.Configuration
26 | import xyz.wallpanel.app.utils.DialogUtils
27 | import dagger.android.support.DaggerAppCompatActivity
28 | import javax.inject.Inject
29 |
30 | class SettingsActivity : DaggerAppCompatActivity() {
31 |
32 | @Inject
33 | lateinit var configuration: Configuration
34 |
35 | @Inject
36 | lateinit var dialogUtils: DialogUtils
37 |
38 | public override fun onCreate(savedInstance: Bundle?) {
39 | super.onCreate(savedInstance)
40 |
41 | setContentView(R.layout.activity_settings)
42 |
43 | supportActionBar?.show()
44 | supportActionBar?.setDisplayHomeAsUpEnabled(true)
45 | supportActionBar?.setDisplayShowHomeEnabled(true)
46 | supportActionBar?.title = (getString(R.string.title_settings))
47 |
48 | lifecycle.addObserver(dialogUtils)
49 | }
50 |
51 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
52 | val id = item.itemId
53 | if (id == android.R.id.home) {
54 | onBackPressed()
55 | return true
56 | }
57 | return super.onOptionsItemSelected(item)
58 | }
59 |
60 | companion object {
61 | const val PERMISSIONS_REQUEST_WRITE_SETTINGS = 200
62 | fun createStartIntent(context: Context): Intent {
63 | return Intent(context, SettingsActivity::class.java)
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/ui/activities/TestActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Wallpanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.ui.activities
18 |
19 | import androidx.appcompat.app.AppCompatActivity
20 | import android.os.Bundle
21 | import android.view.ViewGroup
22 | import android.widget.Button
23 | import xyz.wallpanel.app.R
24 |
25 | class TestActivity : AppCompatActivity() {
26 | override fun onCreate(savedInstanceState: Bundle?) {
27 | super.onCreate(savedInstanceState)
28 | setContentView(R.layout.activity_test)
29 |
30 | val crashButton = Button(this)
31 | crashButton.text = "Test Crash"
32 | crashButton.setOnClickListener {
33 | throw RuntimeException("Test Crash") // Force a crash
34 | }
35 |
36 | addContentView(crashButton, ViewGroup.LayoutParams(
37 | ViewGroup.LayoutParams.MATCH_PARENT,
38 | ViewGroup.LayoutParams.WRAP_CONTENT))
39 | }
40 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/ui/fragments/QrCodeSettingsFragment.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.ui.fragments
18 |
19 | import android.content.Context
20 | import android.os.Bundle
21 | import androidx.preference.SwitchPreference
22 | import android.view.Menu
23 | import android.view.MenuInflater
24 | import android.view.MenuItem
25 | import android.view.View
26 | import androidx.navigation.Navigation
27 | import xyz.wallpanel.app.R
28 | import xyz.wallpanel.app.ui.activities.SettingsActivity
29 | import dagger.android.support.AndroidSupportInjection
30 |
31 | class QrCodeSettingsFragment : BaseSettingsFragment() {
32 |
33 | private var qrCodePreference: SwitchPreference? = null
34 |
35 | override fun onAttach(context: Context) {
36 | AndroidSupportInjection.inject(this)
37 | super.onAttach(context)
38 | setHasOptionsMenu(true)
39 | }
40 |
41 | override fun onActivityCreated(savedInstanceState: Bundle?) {
42 | super.onActivityCreated(savedInstanceState)
43 | if((activity as SettingsActivity).supportActionBar != null) {
44 | (activity as SettingsActivity).supportActionBar!!.setDisplayHomeAsUpEnabled(true)
45 | (activity as SettingsActivity).supportActionBar!!.setDisplayShowHomeEnabled(true)
46 | (activity as SettingsActivity).supportActionBar!!.title = (getString(R.string.title_facedetection_settings))
47 | }
48 | }
49 |
50 | override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
51 | super.onCreateOptionsMenu(menu, inflater)
52 | inflater.inflate(R.menu.menu_help, menu)
53 | }
54 |
55 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
56 | val id = item.itemId
57 | if (id == android.R.id.home) {
58 | view?.let { Navigation.findNavController(it).navigate(R.id.camera_action) }
59 | return true
60 | } else if (id == R.id.action_help) {
61 | showSupport()
62 | return true
63 | }
64 | return super.onOptionsItemSelected(item)
65 | }
66 |
67 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
68 | addPreferencesFromResource(R.xml.pref_qrcode)
69 | }
70 |
71 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
72 |
73 | super.onViewCreated(view, savedInstanceState)
74 |
75 | qrCodePreference = findPreference(getString(R.string.key_setting_camera_qrcodeenabled)) as SwitchPreference
76 |
77 | bindPreferenceSummaryToValue(qrCodePreference!!)
78 | }
79 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/ui/views/WebClientCallback.kt:
--------------------------------------------------------------------------------
1 | package xyz.wallpanel.app.ui.views
2 |
3 | import android.webkit.PermissionRequest
4 |
5 | interface WebClientCallback {
6 | fun askForWebkitPermission(permission: String, requestCode: Int)
7 |
8 | fun complete()
9 |
10 | fun pageLoadComplete(url: String)
11 |
12 | fun setWebkitPermissionRequest(request: PermissionRequest?)
13 |
14 | var isConnected: Boolean
15 |
16 | fun isFinishing(): Boolean
17 |
18 | fun displayProgress(): Boolean
19 |
20 | fun startReloadDelay()
21 |
22 | fun stopReloadDelay()
23 |
24 | fun certPermissionsShown() : Boolean
25 |
26 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/utils/BrowserUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package xyz.wallpanel.app.utils
17 |
18 | import android.content.Intent
19 | import timber.log.Timber
20 |
21 | class BrowserUtils {
22 | /**
23 | * DEPRECATED
24 | * This methods parses url's with intent strings
25 | * "intent:#Intent;launchFlags=0x10000000;component=com.amazon.avod/com.amazon.avod.client.activity.HomeScreenActivity;end"
26 | */
27 | fun parseIntent(url: String): Intent? {
28 | val separated = url.split(";").toTypedArray()
29 | return if (separated.size == 4) {
30 | Timber.d(separated[0]) // this will contain "intent:#Intent"
31 | Timber.d(separated[1]) // this will contain "launch flag"
32 | Timber.d(separated[2]) // this will contain "component"
33 | Timber.d(separated[3]) // this will contain "end"
34 | val component = separated[2].removePrefix("component=")
35 | val classname = component.split("/").toTypedArray()
36 | val pkgName = classname[0] // this will set the packageName:
37 | val clsName = classname[1] // this will set the className:
38 | val intent = Intent()
39 | intent.action = Intent.ACTION_VIEW
40 | intent.setClassName(pkgName, clsName)
41 | intent
42 | } else {
43 | null
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/utils/CameraUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.utils
18 |
19 | import android.content.Context
20 | import android.hardware.Camera
21 | import xyz.wallpanel.app.R
22 | import java.util.ArrayList
23 |
24 | /**
25 | * Created by Michael Ritchie on 7/9/18.
26 | */
27 | class CameraUtils {
28 |
29 | companion object {
30 |
31 | open class CameraList {
32 | var cameraId: Int = 0
33 | var description: String = ""
34 | var width:Int = 640
35 | var height:Int = 480
36 | var orientation:Int = 0
37 | }
38 |
39 | @Throws(RuntimeException::class)
40 | fun getCameraList(context: Context): ArrayList {
41 | val cameraList: ArrayList = ArrayList()
42 | for (i in 0 until Camera.getNumberOfCameras()) {
43 | var description: String
44 | val c = Camera.open(i)
45 | val p = c.parameters
46 | val previewSize = p.previewSize
47 | val width = previewSize.width
48 | val height = previewSize.height
49 | val info = Camera.CameraInfo()
50 | Camera.getCameraInfo(i, info)
51 | val patternString = context.getString(R.string.text_camera_pattern)
52 | val facing =
53 | if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
54 | context.getString(R.string.text_front)
55 | else
56 | context.getString(R.string.text_back)
57 | description = java.text.MessageFormat.format(
58 | patternString,
59 | i,
60 | facing,
61 | info.orientation,
62 | width,
63 | height)
64 | c.stopPreview()
65 | c.release()
66 |
67 | val cameraListItem = CameraList()
68 | cameraListItem.description = description
69 | cameraListItem.cameraId = i
70 | cameraListItem.width = width
71 | cameraListItem.height = height
72 | cameraListItem.orientation = info.orientation
73 | cameraList.add(cameraListItem)
74 | }
75 | return cameraList
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/utils/CrashlyticsDebugTree.kt:
--------------------------------------------------------------------------------
1 | package xyz.wallpanel.app.utils
2 |
3 | import android.util.Log
4 | import timber.log.Timber
5 | import com.google.firebase.crashlytics.FirebaseCrashlytics
6 | import java.lang.Exception
7 | import java.util.*
8 |
9 | class CrashlyticsDebugTree : Timber.Tree() {
10 |
11 | override fun log(priority: Int, tag: String?, message: String, throwable: Throwable?) {
12 | if (priority != Log.ERROR) {
13 | return
14 | }
15 | val crashlytics = FirebaseCrashlytics.getInstance()
16 | crashlytics.setCustomKey(CRASHLYTICS_KEY_PRIORITY, priority)
17 | if (tag != null) crashlytics.setCustomKey(CRASHLYTICS_KEY_TAG, tag)
18 | crashlytics.setCustomKey(CRASHLYTICS_KEY_MESSAGE, message)
19 | if (throwable == null) {
20 | crashlytics.recordException(trimmedException(Exception(message)))
21 | } else {
22 | crashlytics.recordException(throwable)
23 | }
24 | }
25 |
26 | companion object {
27 | private const val CRASHLYTICS_KEY_PRIORITY = "priority"
28 | private const val CRASHLYTICS_KEY_TAG = "tag"
29 | private const val CRASHLYTICS_KEY_MESSAGE = "message"
30 |
31 | private fun trimmedException(e: Exception): Throwable {
32 | val elements = e.stackTrace
33 | var trim = 0
34 | for (i in elements.indices) {
35 | val element = elements[i]
36 | val className = element.className
37 | if (!className.contains("Timber") && !className.contains("CrashlyticsReportingTree")) {
38 | trim = i
39 | break
40 | }
41 | }
42 | e.stackTrace = Arrays.copyOfRange(elements, trim, elements.size)
43 | return e
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/utils/DateUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.utils
18 |
19 | import java.text.SimpleDateFormat
20 | import java.util.Date
21 | import java.util.Locale
22 | import java.util.concurrent.TimeUnit
23 |
24 |
25 | /**
26 | * Date utils
27 | */
28 | object DateUtils {
29 |
30 | var SECONDS_VALUE = 60000
31 | var MINUTES_VALUE = 1800000
32 |
33 | fun generateCreatedAtDate(): String {
34 | val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US)
35 | return dateFormat.format(Date())
36 | }
37 |
38 | fun padTimePickerOutput(timeValue: String): String {
39 | var value = timeValue
40 | if (value.length == 1) {
41 | value = "0$value"
42 | }
43 | return value
44 | }
45 |
46 | fun getHourFromTimePicker(timeValue: String): Int {
47 | val values = timeValue.split(":")
48 | if(values.size > 1) {
49 | val value = values[0].toInt()
50 | return value
51 | }
52 | return 0
53 | }
54 |
55 | fun getMinutesFromTimePicker(timeValue: String): Int {
56 | val values = timeValue.split(":")
57 | if(values.size > 1) {
58 | val value = values[1].toInt()
59 | return value
60 | }
61 | return 0
62 | }
63 |
64 | fun getHourAndMinutesFromTimePicker(timePickerValue: String): Float {
65 | return timePickerValue.replace(":", ".").toFloat()
66 | }
67 |
68 | /**
69 | * This converts the milliseconds to a day of the week, but we try to account
70 | * for time that is shorter than expected from DarkSky API .
71 | * @param apiTime
72 | * @return
73 | */
74 | fun dayOfWeek(apiTime: Long): String {
75 | var time = apiTime
76 | if (apiTime.toString().length == 10) {
77 | time = apiTime * 1000
78 | }
79 | val sdf = SimpleDateFormat("EEEE", Locale.getDefault())
80 | return sdf.format(Date(time))
81 | }
82 |
83 | fun convertInactivityTime(inactivityValue: Long): String {
84 | return if (inactivityValue < SECONDS_VALUE) {
85 | TimeUnit.MILLISECONDS.toSeconds(inactivityValue).toString()
86 | } else if (inactivityValue > MINUTES_VALUE) {
87 | TimeUnit.MILLISECONDS.toHours(inactivityValue).toString()
88 | } else {
89 | TimeUnit.MILLISECONDS.toMinutes(inactivityValue).toString()
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/utils/InternalWebChromeClient.kt:
--------------------------------------------------------------------------------
1 | package xyz.wallpanel.app.utils
2 |
3 | import android.content.res.Resources
4 | import android.os.Build
5 | import android.webkit.JsResult
6 | import android.webkit.PermissionRequest
7 | import android.webkit.WebChromeClient
8 | import android.webkit.WebView
9 | import android.widget.Toast
10 | import androidx.annotation.RequiresApi
11 | import androidx.appcompat.app.AlertDialog
12 | import com.google.android.material.snackbar.Snackbar
13 | import xyz.wallpanel.app.R
14 | import xyz.wallpanel.app.ui.activities.BaseBrowserActivity
15 | import xyz.wallpanel.app.ui.views.WebClientCallback
16 |
17 | class InternalWebChromeClient(val resources: Resources, val callback: WebClientCallback) :
18 | WebChromeClient() {
19 |
20 | var snackbar: Snackbar? = null
21 |
22 | override fun onProgressChanged(view: WebView, newProgress: Int) {
23 | if (newProgress == 100) {
24 | snackbar?.dismiss()
25 | if (view.url != null) {
26 |
27 | } else {
28 | Toast.makeText(
29 | view.context,
30 | resources.getString(R.string.toast_empty_url),
31 | Toast.LENGTH_SHORT
32 | ).show()
33 | callback.complete()
34 | }
35 | return
36 | }
37 | if (callback.displayProgress()) {
38 | val text =
39 | resources.getString(R.string.text_loading_percent, newProgress.toString(), view.url)
40 | if (snackbar == null) {
41 | snackbar = Snackbar.make(view, text, Snackbar.LENGTH_INDEFINITE)
42 | } else {
43 | snackbar?.setText(text)
44 | }
45 | snackbar?.show()
46 | }
47 | }
48 |
49 | @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
50 | override fun onPermissionRequest(request: PermissionRequest?) {
51 | super.onPermissionRequest(request)
52 | callback.setWebkitPermissionRequest(request)
53 | request?.resources?.forEach {
54 | when (it) {
55 | PermissionRequest.RESOURCE_AUDIO_CAPTURE -> {
56 | callback.askForWebkitPermission(
57 | it,
58 | BaseBrowserActivity.REQUEST_CODE_PERMISSION_AUDIO
59 | )
60 | }
61 | PermissionRequest.RESOURCE_VIDEO_CAPTURE -> {
62 | callback.askForWebkitPermission(
63 | it,
64 | BaseBrowserActivity.REQUEST_CODE_PERMISSION_CAMERA
65 | )
66 | }
67 | }
68 | }
69 | }
70 |
71 | override fun onJsAlert(
72 | view: WebView,
73 | url: String,
74 | message: String,
75 | result: JsResult
76 | ): Boolean {
77 | if (view.context != null && !callback.isFinishing()) {
78 | AlertDialog.Builder(view.context)
79 | .setMessage(message)
80 | .setPositiveButton(android.R.string.ok, null)
81 | .show()
82 | }
83 | return true
84 | }
85 |
86 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/utils/LauncherShortcuts.kt:
--------------------------------------------------------------------------------
1 | package xyz.wallpanel.app.utils
2 |
3 | import android.annotation.TargetApi
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.content.pm.ShortcutInfo
7 | import android.content.pm.ShortcutManager
8 | import android.graphics.drawable.Icon
9 | import android.os.Build
10 | import xyz.wallpanel.app.R
11 | import xyz.wallpanel.app.ui.activities.SettingsActivity
12 | import java.util.*
13 |
14 | @TargetApi(Build.VERSION_CODES.N_MR1)
15 | class LauncherShortcuts {
16 | companion object {
17 |
18 | fun createShortcuts(context: Context) {
19 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
20 | val shortcutManager = context.getSystemService(ShortcutManager::class.java)
21 | shortcutManager!!.dynamicShortcuts = Arrays.asList(settingsShortcut(context, 0))
22 | }
23 | }
24 |
25 | /**
26 | * If we ever want to customize the shortcut options
27 | */
28 | fun updateShortcutStatus(context: Context, searchEnabled: Boolean) {
29 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
30 | val shortcutManager = context.getSystemService(ShortcutManager::class.java)
31 | shortcutManager!!.removeAllDynamicShortcuts()
32 | val list = LinkedList()
33 |
34 | if (searchEnabled) {
35 | list.add(settingsShortcut(context, list.size))
36 | }
37 | if (!list.isEmpty()) {
38 | shortcutManager.dynamicShortcuts = list
39 | }
40 | }
41 | }
42 |
43 | private fun settingsShortcut(context: Context, rank: Int): ShortcutInfo {
44 | return ShortcutInfo.Builder(context, context.getString(R.string.shortcut_settings_id))
45 | .setShortLabel(context.getString(R.string.shortcut_settings_shortlabel))
46 | .setLongLabel(context.getString(R.string.shortcut_settings_longlabel))
47 | .setIcon(Icon.createWithResource(context, R.drawable.ic_settings_cyan))
48 | .setDisabledMessage(context.getString(R.string.shortcut_settings_disabled_message))
49 | .setIntent(
50 | Intent(context, SettingsActivity::class.java)
51 | .setAction(Intent.ACTION_VIEW)
52 | .setFlags(
53 | Intent.FLAG_ACTIVITY_NEW_TASK or
54 | Intent.FLAG_ACTIVITY_CLEAR_TOP or
55 | Intent.FLAG_ACTIVITY_CLEAR_TASK))
56 | .setRank(rank)
57 | .build()
58 | }
59 | }
60 |
61 | }
--------------------------------------------------------------------------------
/WallPanelApp/src/main/java/xyz/wallpanel/app/utils/StringUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package xyz.wallpanel.app.utils;
18 |
19 | public class StringUtils {
20 |
21 | private static String strSeparator = ",";
22 |
23 | public static String convertArrayToString(String[] array){
24 | StringBuilder str = new StringBuilder();
25 | for (int i = 0; i < array.length; i++) {
26 | str.append(array[i]);
27 | // Do not append comma at the end of last element
28 | if(i
16 |
17 |
23 |
27 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable-hdpi/ic_stat_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/drawable-hdpi/ic_stat_name.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable-mdpi/ic_stat_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/drawable-mdpi/ic_stat_name.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable-xhdpi/ic_stat_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/drawable-xhdpi/ic_stat_name.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable-xxhdpi/ic_stat_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/drawable-xxhdpi/ic_stat_name.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | -
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | -
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_blue_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | -
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | -
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_blue_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_border.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
9 |
15 |
16 |
17 |
18 | -
23 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_border_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
9 |
15 |
16 |
17 |
18 | -
23 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_border_bottom_corner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
9 |
15 |
16 |
17 |
18 | -
23 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_border_bottom_corner_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
9 |
15 |
16 |
17 |
18 | -
23 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_border_bottom_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
9 |
15 |
16 |
17 |
18 | -
23 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_border_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
9 |
15 |
16 |
17 |
18 | -
23 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_border_left_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
9 |
15 |
16 |
17 |
18 | -
23 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_border_top_corner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
9 |
15 |
16 |
17 |
18 | -
23 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_border_top_corner_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
9 |
15 |
16 |
17 |
18 | -
23 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_disabled.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | -
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | -
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_green.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | -
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | -
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_green_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | -
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | -
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/button_green_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_baseline_backspace.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_baseline_close.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_baseline_help.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_baseline_lock.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_baseline_lock_open.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_baseline_refresh.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_baseline_videocam.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_cloud.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_dashboard.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_dashboard_white.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_directions_run.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_email_black.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_face.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_file_edit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_github_blk.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_help.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_help_black.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_photo_camera.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_radio_button_checked_black.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_radio_button_unchecked_black.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_settings_brightness.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_settings_cyan.xml:
--------------------------------------------------------------------------------
1 |
8 |
13 |
18 |
19 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_social_reddit.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/ic_star_black.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/drawable/logo_front.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout-land/dialog_screen_saver.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
25 |
26 |
33 |
34 |
35 |
41 |
42 |
46 |
47 |
48 |
49 |
56 |
57 |
66 |
67 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout-sw600dp-land/dialog_screen_saver.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
25 |
26 |
33 |
34 |
40 |
41 |
45 |
46 |
47 |
48 |
55 |
56 |
65 |
66 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout-sw600dp/dialog_screen_saver.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
25 |
26 |
33 |
34 |
40 |
41 |
45 |
46 |
47 |
48 |
55 |
56 |
65 |
66 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout-sw720dp-land/dialog_screen_saver.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
25 |
26 |
34 |
35 |
41 |
42 |
46 |
47 |
48 |
49 |
56 |
57 |
66 |
67 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout-sw720dp/dialog_screen_saver.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
25 |
26 |
33 |
34 |
40 |
41 |
45 |
46 |
47 |
48 |
55 |
56 |
65 |
66 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout/activity_browser.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
23 |
29 |
30 |
34 |
35 |
39 |
40 |
46 |
47 |
48 |
49 |
50 |
51 |
62 |
63 |
77 |
78 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout/activity_live_camera.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
23 |
24 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
48 |
49 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
16 |
22 |
23 |
30 |
31 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout/activity_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
24 |
25 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout/activity_welcome.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
23 |
24 |
27 |
28 |
33 |
34 |
37 |
38 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/layout/dialog_screen_saver.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
25 |
26 |
30 |
31 |
32 |
33 |
40 |
41 |
50 |
51 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/menu/menu_dashboard.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/menu/menu_help.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-hdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-hdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-mdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-mdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 | #393C44
20 | #292929
21 | #0EABEE
22 |
23 | #363636
24 | #FCFFFFFF
25 |
26 | #f4f4f4
27 | #E5F4F4F4
28 | #CCF4F4F4
29 |
30 | #CCC6C6C5
31 |
32 | #A3A1A1
33 | #fff4f4f4
34 |
35 |
36 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
29 |
30 |
40 |
41 |
49 |
50 |
54 |
55 |
59 |
60 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | #F4F4F4
21 | #0EABEE
22 | #68c5ed
23 | #ffffff
24 | #36B6ED
25 |
26 | #ff707070
27 | #d8d8d8
28 |
29 | #66000000
30 |
31 | #9E9E9E
32 | #616161
33 | #424242
34 | #FFFFFF
35 | #979797
36 |
37 | #00000000
38 |
39 | #c87dac2f
40 | #ff7dac2f
41 | #ff67932c
42 | #ff67932c
43 | #ff7dac2f
44 | #c8eeee22
45 | #818181
46 | #818181
47 | #ff3c75c4
48 | #4170c4
49 |
50 | #ff000000
51 | #000000
52 | #FFFFFF
53 | #beffffff
54 | #efefef
55 | #c8d7523e
56 | #fff4492c
57 | #ffd3402a
58 | #eeeeee
59 | #eeeeee
60 |
61 | #e5e5e5
62 | #c2c2c2
63 |
64 | #7e7e7c
65 |
66 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | 11sp
20 | 12sp
21 | 14sp
22 | 15sp
23 | 16sp
24 | 18sp
25 | 24sp
26 | 36sp
27 | 11.0sp
28 | 12.0sp
29 | 12dp
30 | 18dp
31 | 24dp
32 | 6dp
33 | 20sp
34 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #68C9F3
4 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/web_hi_res_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/WallPanelApp/src/main/res/web_hi_res_512.png
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/xml/network_config.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 127.0.0.1
13 |
14 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/xml/pref_face.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
33 |
34 |
40 |
41 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/xml/pref_http.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
28 |
29 |
30 |
31 |
32 |
33 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
55 |
56 |
60 |
61 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/WallPanelApp/src/main/res/xml/pref_qrcode.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-minimal
2 | title: "WallPanel"
3 | description: "WallPanel is an Android application for Web Based Dashboards and Home Automation Platforms"
4 | logo: /img/logo.png
5 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
18 |
19 | buildscript {
20 | ext.kotlin_version = '1.6.21'
21 | repositories {
22 | google()
23 | gradlePluginPortal()
24 | mavenCentral()
25 | }
26 | dependencies {
27 | classpath 'com.android.tools.build:gradle:7.3.0'
28 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
29 | classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2'
30 | classpath 'com.google.gms:google-services:4.3.14'
31 | classpath 'gradle.plugin.com.github.sgtsilvio.gradle:android-retrofix:0.4.1'
32 | }
33 | }
34 |
35 | allprojects {
36 | repositories {
37 | google()
38 | gradlePluginPortal()
39 | mavenCentral()
40 | }
41 | }
42 |
43 | task clean(type: Delete) {
44 | delete rootProject.buildDir
45 | }
46 |
47 | ext.deps = [:]
48 | def versions = [:]
49 | versions.lifecycle = "2.5.1"
50 | versions.support = "28.0.0"
51 | versions.navigation = "1.0.0"
52 | versions.constraint_layout = "1.1.0"
53 | versions.retrofit = "2.9.0"
54 | versions.stetho = "1.3.1"
55 | versions.dagger = "2.41"
56 | versions.archVersion = '1.1.1'
57 | versions.archRoomVersion = '1.1.0'
58 | ext.versions = versions
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2022 WallPanel
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software distributed
11 | # under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | # Project-wide Gradle settings.
18 |
19 | # IDE (e.g. Android Studio) users:
20 | # Gradle settings configured through the IDE *will override*
21 | # any settings specified in this file.
22 |
23 | # For more details on how to configure your build environment visit
24 | # http://www.gradle.org/docs/current/userguide/build_environment.html
25 |
26 | # Specifies the JVM arguments used for the daemon process.
27 | # The setting is particularly useful for tweaking memory settings.
28 | android.enableJetifier=true
29 | android.useAndroidX=true
30 | org.gradle.jvmargs=-Xmx1536m
31 |
32 | # When configured, Gradle will run in incubating parallel mode.
33 | # This option should only be used with decoupled projects. More details, visit
34 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
35 | # org.gradle.parallel=true
36 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed May 19 11:27:42 ART 2021
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/img/dashboard1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/img/dashboard1.png
--------------------------------------------------------------------------------
/img/dashboard2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/img/dashboard2.png
--------------------------------------------------------------------------------
/img/dashboard3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/img/dashboard3.png
--------------------------------------------------------------------------------
/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/img/logo.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 WallPanel
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software distributed
11 | * under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | include ':WallPanelApp'
18 |
--------------------------------------------------------------------------------
/website/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | /node_modules
3 |
4 | # Production
5 | /build
6 |
7 | # Generated files
8 | .docusaurus
9 | .cache-loader
10 |
11 | # Misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
--------------------------------------------------------------------------------
/website/.prettierrc:
--------------------------------------------------------------------------------
1 | tabWidth: 2
2 | singleQuote: true
3 | trailingComma: all
4 | bracketSpacing: false
5 | jsxBracketSameLine: true
6 | arrowParens: avoid
7 |
--------------------------------------------------------------------------------
/website/README.md:
--------------------------------------------------------------------------------
1 | # Website
2 |
3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
4 |
5 | ### Installation
6 |
7 | ```
8 | $ yarn
9 | ```
10 |
11 | ### Local Development
12 |
13 | ```
14 | $ yarn start
15 | ```
16 |
17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
18 |
19 | ### Build
20 |
21 | ```
22 | $ yarn build
23 | ```
24 |
25 | This command generates static content into the `build` directory and can be served using any static contents hosting service.
26 |
--------------------------------------------------------------------------------
/website/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
3 | };
4 |
--------------------------------------------------------------------------------
/website/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Getting Started
3 | sidebar_position: 1
4 | ---
5 |
6 | ## Installation
7 |
8 | You can either side load the application to your device from the [release section](https://github.com/thetimewalker/wallpanel-android/releases) or install the application from [Google Play](https://play.google.com/store/apps/details?id=xyz.wallpanel.app).
9 |
10 | :::important
11 | If you have need support for older Android 4.0 devices (those below Android 4.4), you want to use the [legacy version](https://github.com/thanksmister/wallpanel-android-legacy) of the application. Alternatively you can download an APK from the release section prior to release v0.8.8-beta.6
12 | :::
13 |
14 | ## Using the App
15 |
16 | To begin using WallPanel, you need to do two things. First enter the settings screen and reset your settings password. The default code to enter the settings is **`1234`**. There is a floating button on the screen in the lower-right corner.
17 |
18 | 
19 |
20 | Once you enter the settings screen, you can change the settings code to any 4-digit code using, just remember the code will always be needed to enter the settings. Now edit the Dashboard url, this is the web site or home automation platform dashboard you want to use with the application. Note that initially, the application shows the Github page for the project.
21 |
22 | 
23 |
24 | You also have the option in the settings to change the location of the settings button to any of the four corners of the application, as well as make the button transparent. If you make the button transparent, you must recall the last location of the button in order to press the now invisible button on your screen.
25 |
26 | 
27 |
28 | Once you have setup the code and dashboard url, each time you enter the settings, you will be prompted to enter the code.
29 |
30 | 
31 |
--------------------------------------------------------------------------------
/website/docs/launch-external-apps.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Launch External Applications
3 | ---
4 |
5 | Using the url command `{"url": "http://"}`, you can load other applications using the `intent: scheme URL` for that application. For exxample, to launch the Ring app, you would use this as the url schema:
6 |
7 | ```plain
8 | intent:#Intent;launchFlags=0x10000000;component=com.ringapp/.ui.activities.LoginActivity;end
9 | ```
10 |
11 | For a list of more intent schema urls, visit https://support.actiontiles.com/en/communities/12/topics/1255-open-android-app-or-app-activity-via-url-formatted-shortcut.
12 |
--------------------------------------------------------------------------------
/website/docs/limitations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Limitations
3 | ---
4 |
5 | Android devices use WebView to render webpages, This WebView does not have full feature parity with Chrome for Android and therefore pages that render in Chrome may not render nicely in Wall Panel. For example, WebView that shipped with Android 4.4 (KitKat) devices is based on the same code as Chrome for Android version 30.
6 |
7 | This WebView does not have full feature parity with Chrome for Android and is given the version number 30.0.0.0. If you find that you cannot render a webpage, it is most likely that the version of WebView on your device does not support the CSS/HTML of that page. You have little recourse but to update the webpage, as there is nothing to be done to the WebView to make it compatible with your code.
8 |
9 | Setting WallPanel as the default Home application will always load this application as your home. Removing this feature is difficult without uninstalling the application. So please do this is you wish to use the application as a "kiosk" type application.
10 |
--------------------------------------------------------------------------------
/website/docs/remote-control/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Remote Control (MQTT / HTTP)",
3 | "position": 2,
4 | "collapsed": false
5 | }
6 |
--------------------------------------------------------------------------------
/website/docs/remote-control/commands.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: MQTT and HTTP commands
3 | ---
4 |
5 | Interact and control the application and device remotely using either MQTT or HTTP (REST) commands, including using your device as an announcer with Google Text-To-Speach.
6 |
7 | ## Commands
8 |
9 | Key | Value | Example Payload | Description
10 | -|-|-|-
11 | clearCache | true | ```{"clearCache": true}``` | Clears the browser cache
12 | eval | JavaScript | ```{"eval": "alert('Hello World!');"}``` | Evaluates Javascript in the dashboard
13 | audio | URL | ```{"audio": "http://"}``` | Play the audio specified by the URL immediately
14 | relaunch | true | ```{"relaunch": true}``` | Relaunches the dashboard from configured launchUrl
15 | reload | true | ```{"reload": true}``` | Reloads the current page immediately
16 | url | URL | ```{"url": "http://"}``` | Browse to a new URL immediately
17 | wake | true | ```{"wake": true, "wakeTime": 180}``` | Wakes the screen if it is asleep. Optional wakeTime (in seconds). If no wake time provided, screen will wake but return to screensaver mode on user inactivity. Sending false value will return app to normal screensaver mode and display screensaver on user inactivity.
18 | wake | false | ```{"wake": false}``` | Release screen wake (Note: screen will not turn off before Androids Display Timeout finished)
19 | speak | data | ```{"speak": "Hello!"}``` | Uses the devices TTS to speak the message
20 | settings | data | ```{"settings": true}``` | Opens the settings screen remotely.
21 | brightness | data | ```{"brightness": 1}``` | Changes the screens brightness, value 1-255.
22 | camera | data | ```{"camera": true}``` | Turns on/off camera, this will also disable streaming, motion, QRCode, and face detection.
23 | volume | data | ```{"volume": 100}``` | Changes the audio volume, value 0-100 (in %. Does not effect TTS volume).
24 |
25 | * The base topic value (default is "mywallpanel") should be unique to each device running the application unless you want all devices to receive the same command. The base topic and can be changed in the applications ```MQTT settings```.
26 | * Commands are constructed via valid JSON. It is possible to string multiple commands together:
27 | * eg, ```{"clearCache":true, "relaunch":true}```
28 | * For REST
29 | * POST the JSON to URL ```http://:2971/api/command```
30 | * For MQTT
31 | * WallPanel subscribes to topic ```wallpanel/[baseTopic]/command```
32 | * Default Topic: ```wallpanel/mywallpanel/command```
33 | * Publish a JSON payload to this topic (be mindful of quotes in JSON should be single quotes not double)
34 |
35 | ## Google Text-To-Speech (TTS) Command
36 |
37 | You can send a command using either HTTP or MQTT to have the device speak a message using Google's Text-To-Speach. Note that the device must be running Android Lollipop or above.
38 |
39 | Example format for the message topic and payload:
40 |
41 | ```json
42 | {"topic":"wallpanel/mywallpanel/command", "payload":"{'speak':'Hello!'}"}
43 | ```
44 |
45 | If you are using HTTP and sending text with special characters, such as those used in a Cyrillic or Spanish language, you would need to make sure your content type is set to utf-8, here is an example using curl to post a message in Spanish:
46 |
47 | ```sh
48 | curl --location --request POST 'http://192.168.1.1:2971/api/command' \
49 | --header 'Content-Type: application/json;charset=UTF-8' \
50 | --data-raw '{
51 | "speak": "¡Aló mundo"
52 | }'
53 | ```
54 |
--------------------------------------------------------------------------------
/website/docs/remote-control/mqtt-setup.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: MQTT Setup
3 | sidebar_position: 1
4 | ---
5 |
6 | MQTT can be used by the application to [publish application data, user presence, and device sensor data](./sensors.md). You can also use MQTT to [send commands to the application](./commands.md). To setup the application for MQTT, enable it under the setting.
7 |
8 | 
9 |
10 | You will need your MQTT broker IP address and port number if different from the default. There is an option to use SSL with the port 8883. Usually enter the IP address without http/https (192.168.1.1) to use a TCP connection to the broker. You can also use http/https by entering the fully qualified url (https://192.168.1.1).
11 |
12 | The base topic `wallpanel/mywallpanel` allows the device to send and receive MQTT commands or messages. The base topic should be unique to each device if you want the device to operate independently from other devices running the same application in your network. If all devices have the same base topic, then sending a command will mean all devices receive the command.
13 |
14 | If needed, add your MQTT username and password. The client id is the unique identifier of this device with the MQTT broker. It can be changed, but should be different from other applications on the same network.
15 |
16 | 
17 |
18 | Finally we have MQTT discovery. Enabling MQTT Discovery will publish device sensor data on the MQTT channel that can be discovered automatically by your home automation platform. Note that for sensor data, you must also enable sensor data publishing in the sensor settings.
19 |
20 | 
21 |
--------------------------------------------------------------------------------
/website/docs/screensaver.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Screensaver and Brightness Control
3 | ---
4 |
5 | On some older devices, there is no screensaver support such as Google Daydream that automatically dims the screen. Therefore the application provides a screensaver feature. This feature along with the screen brightness option, allows the screen to dim when the screensaver is active. With the Camera and Motion feature, the device can be automatically awaken when motion is detected. Optionally, you can send an MQTT command to wake the screen or just touch the screen to deactivate the screensaver.
6 |
7 | There is setting to dim screen a set percentage when the screensaver is active, this requires the screen brightness setting be enabled. When set to a value above 0%, the screen will dim by the percent value set when the screensaver is active. So if the setting is 75%, the screen will dim to a value that is 75% of the default device brightness levels.
8 |
9 | Using the screen brightness option requires some extra permissions. This is because controlling the devices screen brightness is considered a dangerous permission by Google and so users have to manually turn this on. When you first select the screen brightness option, you will be taken to the setting on your device to enable the permission. The screen brightness feature behaves in the following manner:
10 |
11 | - There is a general brightness setting that must be enabled (and permissions given) in order for the application to manually set the device brightness. If at any time you revoke the permissions in the device settings for the application to control the brightness, this option will be disabled.
12 |
13 | - The brightness mode can be disabled in the settings, returning the device back to its automatic brightness control. If brightness is disabled the application will no longer be able to change the devices brightness level including via MQTT commands.
14 |
15 | - Brightness level is read at the time brightness control is enabled and permissions granted. However, there is also a new capture button in the settings to manually capture the devices current brightness level. To use this, first go into the app settings, then adjust your devices brightness level, then press the capture button to save the new brightness level. The application will then use this brightness level to set the device brightness level.
16 |
17 | - If you have brightness enabled, you can at any time manually set a new brightness level using the MQTT commands (see commands section above). The device will then use the new setting as the default brightness level of the device.
18 |
19 |
--------------------------------------------------------------------------------
/website/docs/video-streaming.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Webcam MJPEG Video Streaming
3 | ---
4 |
5 | If video streaming is enabled, then the stream can be accessed with this URL:
6 |
7 | ```plain
8 | http://yourip:2971/camera/stream
9 | ```
10 |
--------------------------------------------------------------------------------
/website/docusaurus.config.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | // Note: type annotations allow type checking and IDEs autocompletion
3 |
4 | const lightCodeTheme = require('prism-react-renderer/themes/github');
5 | const darkCodeTheme = require('prism-react-renderer/themes/dracula');
6 |
7 | /** @type {import('@docusaurus/types').Config} */
8 | const config = {
9 | title: 'WallPanel',
10 | tagline: 'Android application for web-based dashboards',
11 | url: 'https://wallpanel.xyz',
12 | baseUrl: '/',
13 | onBrokenLinks: 'throw',
14 | onBrokenMarkdownLinks: 'warn',
15 | favicon: 'img/favicon.ico',
16 | organizationName: 'TheTimeWalker',
17 | projectName: 'wallpanel-android',
18 |
19 | presets: [
20 | [
21 | 'classic',
22 | /** @type {import('@docusaurus/preset-classic').Options} */
23 | ({
24 | docs: {
25 | sidebarPath: require.resolve('./sidebars.js'),
26 | editUrl:
27 | 'https://github.com/TheTimeWalker/wallpanel-android/tree/master/website/',
28 | },
29 | theme: {
30 | customCss: require.resolve('./src/css/custom.css'),
31 | },
32 | }),
33 | ],
34 | ],
35 |
36 | themeConfig:
37 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
38 | ({
39 | colorMode: {
40 | defaultMode: 'dark',
41 | disableSwitch: true,
42 | },
43 | navbar: {
44 | title: 'WallPanel',
45 | logo: {
46 | alt: 'WallPanel Logo',
47 | src: 'img/logo.png',
48 | },
49 | items: [
50 | {
51 | type: 'doc',
52 | docId: 'getting-started',
53 | position: 'left',
54 | label: 'Getting Started',
55 | },
56 | {
57 | to: 'privacy-policy',
58 | position: 'left',
59 | label: 'Privacy Policy',
60 | },
61 | {
62 | href: 'https://github.com/TheTimeWalker/wallpanel-android',
63 | label: 'GitHub',
64 | position: 'right',
65 | },
66 | ],
67 | },
68 | footer: {
69 | style: 'dark',
70 | copyright: `Copyright © ${new Date().getFullYear()} WallPanel Contributors. Built with Docusaurus.`,
71 | },
72 | prism: {
73 | theme: lightCodeTheme,
74 | darkTheme: darkCodeTheme,
75 | },
76 | }),
77 | };
78 |
79 | module.exports = config;
80 |
--------------------------------------------------------------------------------
/website/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "website",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "docusaurus": "docusaurus",
7 | "start": "docusaurus start",
8 | "build": "docusaurus build",
9 | "swizzle": "docusaurus swizzle",
10 | "deploy": "docusaurus deploy",
11 | "clear": "docusaurus clear",
12 | "serve": "docusaurus serve",
13 | "write-translations": "docusaurus write-translations",
14 | "write-heading-ids": "docusaurus write-heading-ids",
15 | "typecheck": "tsc"
16 | },
17 | "dependencies": {
18 | "@docusaurus/core": "^2.1.0",
19 | "@docusaurus/preset-classic": "^2.1.0",
20 | "@mdx-js/react": "^1.6.22",
21 | "clsx": "^1.2.1",
22 | "prism-react-renderer": "^1.3.5",
23 | "react": "^17.0.2",
24 | "react-dom": "^17.0.2"
25 | },
26 | "devDependencies": {
27 | "@docusaurus/module-type-aliases": "^2.1.0",
28 | "@tsconfig/docusaurus": "^1.0.6",
29 | "typescript": "^4.8.2"
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.5%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/website/sidebars.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
4 | const sidebars = {
5 | docsSidebar: [{type: 'autogenerated', dirName: '.'}],
6 | };
7 |
8 | module.exports = sidebars;
9 |
--------------------------------------------------------------------------------
/website/src/components/HomepageFeatures/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import clsx from 'clsx';
3 | import styles from './styles.module.css';
4 |
5 | type FeatureItem = {
6 | title: string;
7 | description: JSX.Element;
8 | };
9 |
10 | const FeatureList: FeatureItem[] = [
11 | {
12 | title: 'Easy and Free',
13 | description: (
14 | <>
15 | WallPanel allows any Android 4.4+ or FireOS tablet to display web-based
16 | dashboards. It is free and open-source. Use it for Home Assistant
17 | dashboards, security camera monitoring, or anything else!
18 | >
19 | ),
20 | },
21 | {
22 | title: 'Remote Control',
23 | description: (
24 | <>
25 | WallPanel can be controlled via MQTT or HTTP, allowing you to remotely
26 | navigate to other web pages, speak (Text to Speech), play audio, change
27 | the brightness, and more using MQTT. Plus, WallPanel publishes sensors
28 | to MQTT so you can easily track the tablet's battery life, temperature,
29 | and more.
30 | >
31 | ),
32 | },
33 | {
34 | title: 'Video streaming and motion detection',
35 | description: (
36 | <>
37 | Streaming MJPEG server support using the device camera. Camera support
38 | for motion detection, face detection, and QR Code reading. Screensaver
39 | feature that can be dismissed with motion or face detection.
40 | >
41 | ),
42 | },
43 | ];
44 |
45 | function Feature({title, description}: FeatureItem) {
46 | return (
47 |
48 |
49 |
{title}
50 |
{description}
51 |
52 |
53 | );
54 | }
55 |
56 | export default function HomepageFeatures(): JSX.Element {
57 | return (
58 |
59 |
60 |
61 | {FeatureList.map((props, idx) => (
62 |
63 | ))}
64 |
65 |
66 |
67 | );
68 | }
69 |
--------------------------------------------------------------------------------
/website/src/components/HomepageFeatures/styles.module.css:
--------------------------------------------------------------------------------
1 | .features {
2 | display: flex;
3 | align-items: center;
4 | padding: 2rem 0;
5 | width: 100%;
6 | }
7 |
--------------------------------------------------------------------------------
/website/src/css/custom.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Any CSS included here will be global. The classic template
3 | * bundles Infima by default. Infima is a CSS framework designed to
4 | * work well for content-centric websites.
5 | */
6 |
7 |
8 | /* You can override the default Infima variables here. */
9 | :root {
10 | --ifm-color-primary: #2e8555;
11 | --ifm-color-primary-dark: #29784c;
12 | --ifm-color-primary-darker: #277148;
13 | --ifm-color-primary-darkest: #205d3b;
14 | --ifm-color-primary-light: #33925d;
15 | --ifm-color-primary-lighter: #359962;
16 | --ifm-color-primary-lightest: #3cad6e;
17 | --ifm-code-font-size: 95%;
18 | }
19 |
20 | /* For readability concerns, you should choose a lighter palette in dark mode. */
21 | [data-theme='dark'] {
22 | --ifm-color-primary: #5ec6f2;
23 | --ifm-color-primary-dark: #3fbbef;
24 | --ifm-color-primary-darker: #2fb5ee;
25 | --ifm-color-primary-darkest: #129eda;
26 | --ifm-color-primary-light: #7dd1f5;
27 | --ifm-color-primary-lighter: #8dd7f6;
28 | --ifm-color-primary-lightest: #bbe7fa;
29 | }
30 |
31 | .docusaurus-highlight-code-line {
32 | background-color: rgba(0, 0, 0, 0.1);
33 | display: block;
34 | margin: 0 calc(-1 * var(--ifm-pre-padding));
35 | padding: 0 var(--ifm-pre-padding);
36 | }
37 |
38 | [data-theme='dark'] .docusaurus-highlight-code-line {
39 | background-color: rgba(0, 0, 0, 0.3);
40 | }
41 |
--------------------------------------------------------------------------------
/website/src/pages/index.module.css:
--------------------------------------------------------------------------------
1 | /**
2 | * CSS files with the .module.css suffix will be treated as CSS modules
3 | * and scoped locally.
4 | */
5 |
6 | .heroBanner {
7 | background-color: var(--ifm-color-primary-darkest);
8 | padding: 4rem 0;
9 | text-align: center;
10 | position: relative;
11 | overflow: hidden;
12 | }
13 |
14 | [data-theme=dark] .heroBanner {
15 | color: var(--ifm-heading-color);
16 | }
17 |
18 | @media screen and (max-width: 996px) {
19 | .heroBanner {
20 | padding: 2rem;
21 | }
22 | }
23 |
24 | .buttons {
25 | display: flex;
26 | align-items: center;
27 | justify-content: center;
28 | }
29 |
--------------------------------------------------------------------------------
/website/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import clsx from "clsx";
3 | import Layout from "@theme/Layout";
4 | import Link from "@docusaurus/Link";
5 | import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
6 | import styles from "./index.module.css";
7 | import HomepageFeatures from "@site/src/components/HomepageFeatures";
8 |
9 | function HomepageHeader() {
10 | const { siteConfig } = useDocusaurusContext();
11 | return (
12 |
26 | );
27 | }
28 |
29 | export default function Home(): JSX.Element {
30 | const { siteConfig } = useDocusaurusContext();
31 | return (
32 |
36 |
37 |
38 |
39 |
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/website/static/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/.nojekyll
--------------------------------------------------------------------------------
/website/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/img/favicon.ico
--------------------------------------------------------------------------------
/website/static/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/img/logo.png
--------------------------------------------------------------------------------
/website/static/img/mqtt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/img/mqtt.png
--------------------------------------------------------------------------------
/website/static/img/mqtt_client.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/img/mqtt_client.png
--------------------------------------------------------------------------------
/website/static/img/mqtt_discovery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/img/mqtt_discovery.png
--------------------------------------------------------------------------------
/website/static/img/settings_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/img/settings_button.png
--------------------------------------------------------------------------------
/website/static/img/settings_button_options.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/img/settings_button_options.png
--------------------------------------------------------------------------------
/website/static/img/settings_code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/img/settings_code.png
--------------------------------------------------------------------------------
/website/static/img/settings_dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheTimeWalker/wallpanel-android/2775abc1a9428209c9bbed04bb2d8bd6142d9b0d/website/static/img/settings_dashboard.png
--------------------------------------------------------------------------------
/website/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // This file is not used in compilation. It is here just for a nice editor experience.
3 | "extends": "@tsconfig/docusaurus/tsconfig.json",
4 | "compilerOptions": {
5 | "baseUrl": "."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------