[SHARED] Add info about running as admin on temperatures
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
# Project
|
||||
|
||||
This is a compose multiplatform project build for Android, iOS, JVM and web. App is focused around
|
||||
hardware and software of the devices. App is built using MVVM architecture with AndroidX lifecycle
|
||||
and Kotlin Coroutines for asynchronous programming. It is using DataStore for key-value storage.
|
||||
|
||||
# Commands
|
||||
|
||||
- Run tests: `./gradlew allTests`
|
||||
- Format code: `./gradlew spotlessApply`
|
||||
|
||||
# Code style
|
||||
|
||||
- Use 4 spaces for indentation
|
||||
- Pass data to VM with Interactor
|
||||
- From VM expose data as StateFlow using single UiState
|
||||
- For events use Channel<Event>(Channel.BUFFERED) and observe them in compose with ObserveAsEvents
|
||||
- In VM use `on` prefix for callback functions like `onEvent`, `onClick` etc.
|
||||
- Use composeResources for all strings
|
||||
@@ -212,6 +212,7 @@
|
||||
|
||||
<string name="no_temp_data">Je mi líto, nemohu najít žádné teplotní senzory :-(</string>
|
||||
<string name="no_temp_data_admin_required">Čtení teplotních senzorů vyžaduje oprávnění správce. Spusťte aplikaci jako správce pro přístup k teplotním údajům.</string>
|
||||
<string name="temp_admin_required_snackbar">Pro načtení teplot prosím spusťte jako správce</string>
|
||||
<string name="temp_thermal_state">Tepelný stav: %1$s</string>
|
||||
<string name="temp_thermal_state_nominal">Nominální</string>
|
||||
<string name="temp_thermal_state_fair">Dobrý</string>
|
||||
|
||||
@@ -212,6 +212,7 @@
|
||||
|
||||
<string name="no_temp_data">Entschuldigung, ich kann keine Temperatursensoren finden :-(</string>
|
||||
<string name="no_temp_data_admin_required">Das Lesen von Temperatursensoren erfordert Administratorrechte. Bitte führen Sie die Anwendung als Administrator aus, um auf Temperaturdaten zuzugreifen.</string>
|
||||
<string name="temp_admin_required_snackbar">Bitte als Administrator ausführen, um Temperaturen abzurufen</string>
|
||||
<string name="temp_thermal_state">Thermischer Zustand: %1$s</string>
|
||||
<string name="temp_thermal_state_nominal">Nominal</string>
|
||||
<string name="temp_thermal_state_fair">Gut</string>
|
||||
|
||||
@@ -220,6 +220,7 @@
|
||||
<!--Temp-->
|
||||
<string name="no_temp_data">Lo siento, no puedo encontrar sensores de temperatura :-(</string>
|
||||
<string name="no_temp_data_admin_required">La lectura de los sensores de temperatura requiere privilegios de administrador. Por favor, ejecute la aplicación como administrador para acceder a los datos de temperatura.</string>
|
||||
<string name="temp_admin_required_snackbar">Por favor, ejecute como administrador para obtener las temperaturas</string>
|
||||
<string name="temp_thermal_state">Estado térmico: %1$s</string>
|
||||
<string name="temp_thermal_state_nominal">Nominal</string>
|
||||
<string name="temp_thermal_state_fair">Aceptable</string>
|
||||
|
||||
@@ -221,6 +221,7 @@
|
||||
<!--Temp-->
|
||||
<string name="no_temp_data">Przepraszam, nie mogłem znaleźć sensorów temperatury :-(</string>
|
||||
<string name="no_temp_data_admin_required">Odczyt sensorów temperatury wymaga uprawnień administratora. Uruchom aplikację jako administrator, aby uzyskać dostęp do danych temperatury.</string>
|
||||
<string name="temp_admin_required_snackbar">Uruchom jako administrator, aby pobrać dane o temperaturze</string>
|
||||
<string name="temp_thermal_state">Stan termiczny: %1$s</string>
|
||||
<string name="temp_thermal_state_nominal">Nominalny</string>
|
||||
<string name="temp_thermal_state_fair">Umiarkowany</string>
|
||||
|
||||
@@ -263,6 +263,7 @@
|
||||
<!--Temp-->
|
||||
<string name="no_temp_data">Sorry I can't find temperature sensors :-(</string>
|
||||
<string name="no_temp_data_admin_required">Reading temperature sensors requires administrator privileges. Please run the application as administrator to access temperature data.</string>
|
||||
<string name="temp_admin_required_snackbar">Please run as administrator to fetch temperatures</string>
|
||||
<string name="celsius" translatable="false">°C</string>
|
||||
<string name="fahrenheit" translatable="false">°F</string>
|
||||
<string name="kelvin" translatable="false">K</string>
|
||||
|
||||
+12
@@ -36,6 +36,8 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -63,8 +65,10 @@ import com.kgurgul.cpuinfo.shared.ic_battery
|
||||
import com.kgurgul.cpuinfo.shared.ic_cpu_temp
|
||||
import com.kgurgul.cpuinfo.shared.no_temp_data
|
||||
import com.kgurgul.cpuinfo.shared.no_temp_data_admin_required
|
||||
import com.kgurgul.cpuinfo.shared.temp_admin_required_snackbar
|
||||
import com.kgurgul.cpuinfo.shared.temperature
|
||||
import com.kgurgul.cpuinfo.ui.components.CpuPullToRefreshBox
|
||||
import com.kgurgul.cpuinfo.ui.components.CpuSnackbar
|
||||
import com.kgurgul.cpuinfo.ui.components.PrimaryTopAppBar
|
||||
import com.kgurgul.cpuinfo.ui.components.VerticalScrollbar
|
||||
import com.kgurgul.cpuinfo.ui.theme.CpuInfoTheme
|
||||
@@ -108,9 +112,17 @@ fun TemperatureScreen(viewModel: TemperatureViewModel = koinViewModel()) {
|
||||
|
||||
@Composable
|
||||
fun TemperatureScreen(uiState: TemperatureViewModel.UiState) {
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val adminRequiredMessage = stringResource(Res.string.temp_admin_required_snackbar)
|
||||
LaunchedEffect(uiState.isAdminRequired) {
|
||||
if (uiState.isAdminRequired) {
|
||||
snackbarHostState.showSnackbar(adminRequiredMessage)
|
||||
}
|
||||
}
|
||||
Scaffold(
|
||||
topBar = { PrimaryTopAppBar(title = stringResource(Res.string.temperature)) },
|
||||
contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal),
|
||||
snackbarHost = { SnackbarHost(snackbarHostState) { data -> CpuSnackbar(data) } },
|
||||
) { paddingValues ->
|
||||
CpuPullToRefreshBox(
|
||||
isRefreshing = uiState.isLoading,
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright KG Soft
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.kgurgul.cpuinfo.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@Composable
|
||||
fun <T> ObserveAsEvents(
|
||||
flow: Flow<T>,
|
||||
key1: Any? = null,
|
||||
key2: Any? = null,
|
||||
state: Lifecycle.State = Lifecycle.State.STARTED,
|
||||
onEvent: suspend (T) -> Unit,
|
||||
) {
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
LaunchedEffect(lifecycleOwner.lifecycle, key1, key2) {
|
||||
lifecycleOwner.repeatOnLifecycle(state) {
|
||||
withContext(Dispatchers.Main.immediate) { flow.collect(onEvent) }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user