WIP: [android] convert help screen to compose #5179
12 changed files with 673 additions and 586 deletions
|
@ -25,6 +25,10 @@ buildscript {
|
|||
// Add a parameter to force Firebase.
|
||||
ext.googleFirebaseServicesEnabled = project.hasProperty('firebase') ?: googleFirebaseServicesDefault
|
||||
|
||||
// See https://developer.android.com/jetpack/androidx/releases/compose-kotlin
|
||||
// to see which kotlin version is compatible with compose
|
||||
ext.kotlin_version = '1.8.21'
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.0'
|
||||
|
||||
|
@ -45,6 +49,8 @@ buildscript {
|
|||
|
||||
classpath('com.github.triplet.gradle:play-publisher:3.8.3')
|
||||
classpath('ru.cian:huawei-publish-gradle-plugin:1.4.0')
|
||||
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,6 +71,7 @@ if (googleFirebaseServicesEnabled) {
|
|||
}
|
||||
apply plugin: 'com.github.triplet.play'
|
||||
apply plugin: 'ru.cian.huawei-publish-gradle-plugin'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
dependencies {
|
||||
// Google Mobile Services
|
||||
|
@ -82,10 +89,30 @@ dependencies {
|
|||
implementation 'com.google.firebase:firebase-crashlytics-ndk'
|
||||
}
|
||||
|
||||
// This line is added as a workaround for duplicate classes error caused by some outdated dependency:
|
||||
// > A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
|
||||
// We don't use Kotlin, but some dependencies are actively using it.
|
||||
implementation(platform('org.jetbrains.kotlin:kotlin-bom:1.8.21'))
|
||||
// Kotlin
|
||||
implementation 'androidx.core:core-ktx:1.10.1'
|
||||
implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlin_version"))
|
||||
|
||||
// Dependencies for Jetpack Compose
|
||||
// See https://developer.android.com/jetpack/compose/setup#setup-compose
|
||||
def composeBom = platform('androidx.compose:compose-bom:2023.04.01')
|
||||
implementation composeBom
|
||||
androidTestImplementation composeBom
|
||||
// Material Design 2
|
||||
implementation 'androidx.compose.material:material'
|
||||
// Android Studio Preview support
|
||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
||||
debugImplementation 'androidx.compose.ui:ui-tooling'
|
||||
// Optional - Integration with activities
|
||||
implementation 'androidx.activity:activity-compose:1.7.1'
|
||||
// Optional - Integration with ViewModels
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1'
|
||||
// Optional - Integration with LiveData
|
||||
implementation 'androidx.compose.runtime:runtime-livedata'
|
||||
// Optional - Allows controlling status bar and navigation bar
|
||||
implementation "com.google.accompanist:accompanist-systemuicontroller:0.31.2-alpha"
|
||||
|
||||
|
||||
implementation 'androidx.annotation:annotation:1.6.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
|
@ -139,6 +166,15 @@ android {
|
|||
|
||||
buildFeatures {
|
||||
dataBinding = true
|
||||
compose true
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.4.7"
|
||||
}
|
||||
// All properties are read from gradle.properties file
|
||||
compileSdkVersion propCompileSdkVersion.toInteger()
|
||||
|
|
|
@ -4,7 +4,7 @@ propCompileSdkVersion=33
|
|||
propBuildToolsVersion=34.0.0
|
||||
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx1024m -Xms256m
|
||||
org.gradle.jvmargs=-Xmx2048m -Xms256m
|
||||
android.useAndroidX=true
|
||||
android.native.buildOutput=verbose
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/content_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/margin_base"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/version"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
android:textIsSelectable="true"
|
||||
android:selectAllOnFocus="true"
|
||||
tools:text="2021.10.15-15-Google" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/data_version"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
android:textIsSelectable="true"
|
||||
android:selectAllOnFocus="true"
|
||||
tools:text="OpenStreetMap Data: 3 January 2022" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_marginBottom="@dimen/margin_base"
|
||||
android:layout_marginStart="@dimen/margin_base"
|
||||
android:layout_marginEnd="@dimen/margin_base"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
android:text="@string/about_description"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/donate"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/donate"
|
||||
app:drawableStartCompat="@drawable/ic_donate" />
|
||||
|
||||
<TextView android:id="@+id/report"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/report_a_bug"
|
||||
app:drawableStartCompat="@drawable/ic_report_a_bug"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/support_us"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/how_to_support_us"
|
||||
app:drawableStartCompat="@drawable/ic_contribute" />
|
||||
|
||||
<TextView android:id="@+id/faq"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/faq"
|
||||
app:drawableStartCompat="@drawable/ic_question_mark"/>
|
||||
|
||||
<TextView android:id="@+id/news"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/news"
|
||||
app:drawableStartCompat="@drawable/ic_news"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rate"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/rate_the_app"
|
||||
app:drawableStartCompat="@drawable/ic_rate" />
|
||||
|
||||
<View android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="@dimen/margin_quarter"
|
||||
android:layout_marginBottom="@dimen/margin_quarter"
|
||||
android:background="?dividerHorizontal"/>
|
||||
|
||||
<TextView android:id="@+id/telegram"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/telegram"
|
||||
app:drawableStartCompat="@drawable/ic_telegram" />
|
||||
|
||||
<TextView android:id="@+id/github"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/github"
|
||||
app:drawableStartCompat="@drawable/ic_github"/>
|
||||
|
||||
<TextView android:id="@+id/web"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/website"
|
||||
app:drawableStartCompat="@drawable/ic_website"/>
|
||||
|
||||
<TextView android:id="@+id/email"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/email"
|
||||
app:drawableStartCompat="@drawable/ic_email"/>
|
||||
|
||||
<TextView android:id="@+id/matrix"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/matrix"
|
||||
app:drawableStartCompat="@drawable/ic_matrix"/>
|
||||
|
||||
<TextView android:id="@+id/mastodon"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/mastodon"
|
||||
app:drawableStartCompat="@drawable/ic_mastodon"/>
|
||||
|
||||
<TextView android:id="@+id/facebook"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/facebook"
|
||||
app:drawableStartCompat="@drawable/ic_facebook"/>
|
||||
|
||||
<TextView android:id="@+id/twitter"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/twitter"
|
||||
app:drawableStartCompat="@drawable/ic_twitterx"/>
|
||||
|
||||
<TextView android:id="@+id/instagram"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/instagram"
|
||||
app:drawableStartCompat="@drawable/ic_instagram"/>
|
||||
|
||||
<TextView android:id="@+id/openstreetmap"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/openstreetmap"
|
||||
app:drawableStartCompat="@drawable/ic_openstreetmap"/>
|
||||
|
||||
<View android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="@dimen/margin_quarter"
|
||||
android:layout_marginBottom="@dimen/margin_quarter"
|
||||
android:background="?dividerHorizontal"/>
|
||||
<TextView android:id="@+id/privacy_policy"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/privacy_policy"/>
|
||||
<TextView android:id="@+id/term_of_use_link"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/terms_of_use"/>
|
||||
<TextView android:id="@+id/copyright"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/copyright"/>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<include layout="@layout/shadow_top"/>
|
||||
</FrameLayout>
|
|
@ -1,242 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?cardBackground"
|
||||
android:fadeScrollbars="false"
|
||||
android:fillViewport="true">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/margin_base">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/about_logo"
|
||||
android:layout_height="@dimen/about_logo"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
android:contentDescription="@string/app_name"
|
||||
android:src="@drawable/logo"
|
||||
app:tint="?attr/colorLogo" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/version"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="2021.10.15-15-Google" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_base"
|
||||
android:text="@string/about_headline"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="@style/MwmTextAppearance.Headline"
|
||||
android:textColor="?android:textColorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
android:text="@string/about_proposition_1"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
android:textColor="?android:textColorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
android:text="@string/about_proposition_2"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
android:textColor="?android:textColorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
android:text="@string/about_proposition_3"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
android:textColor="?android:textColorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
android:fontFamily="@string/robotoRegular"
|
||||
android:text="@string/about_developed_by_enthusiasts"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body2"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/osm_logo"
|
||||
android:layout_width="@dimen/osm_logo"
|
||||
android:layout_height="@dimen/osm_logo"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/openstreetmap"
|
||||
android:src="@drawable/ic_openstreetmap_color"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/osm_presentation"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/margin_half"
|
||||
android:fontFamily="@string/robotoRegular"
|
||||
android:includeFontPadding="false"
|
||||
android:text="@string/osm_presentation"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body2"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/osm_logo"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/donate"
|
||||
style="@style/MwmWidget.Button.Accent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
android:fontFamily="@string/robotoMedium"
|
||||
android:padding="@dimen/margin_quarter"
|
||||
android:text="@string/donate" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/report"
|
||||
style="@style/MwmWidget.Button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_base"
|
||||
android:background="@color/light_gray"
|
||||
android:fontFamily="@string/robotoMedium"
|
||||
android:text="@string/report_a_bug"
|
||||
android:textColor="@color/text_dark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/support_us"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/how_to_support_us"
|
||||
app:drawableStartCompat="@drawable/ic_donate" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/faq"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/faq"
|
||||
app:drawableStartCompat="@drawable/ic_question_mark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/news"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/news"
|
||||
app:drawableStartCompat="@drawable/ic_news" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rate"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/rate_the_app"
|
||||
app:drawableStartCompat="@drawable/ic_rate" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/telegram"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/telegram"
|
||||
app:drawableStartCompat="@drawable/ic_telegram" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/github"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/github"
|
||||
app:drawableStartCompat="@drawable/ic_github" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/web"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/website"
|
||||
app:drawableStartCompat="@drawable/ic_website" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/email"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/email"
|
||||
app:drawableStartCompat="@drawable/ic_email" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrix"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/matrix"
|
||||
app:drawableStartCompat="@drawable/ic_matrix" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/mastodon"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/mastodon"
|
||||
app:drawableStartCompat="@drawable/ic_mastodon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/facebook"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/facebook"
|
||||
app:drawableStartCompat="@drawable/ic_facebook" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/twitter"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/twitter"
|
||||
app:drawableStartCompat="@drawable/ic_twitterx" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/instagram"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/instagram"
|
||||
app:drawableStartCompat="@drawable/ic_instagram" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/openstreetmap"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/openstreetmap"
|
||||
app:drawableStartCompat="@drawable/ic_openstreetmap" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginBottom="@dimen/margin_quarter"
|
||||
android:layout_marginTop="@dimen/margin_quarter"
|
||||
android:background="?dividerHorizontal" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/privacy_policy"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/privacy_policy" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/term_of_use_link"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/terms_of_use" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/copyright"
|
||||
style="@style/MwmWidget.TextView.Item"
|
||||
android:text="@string/copyright" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
|
@ -40,7 +40,7 @@ public class CopyrightFragment extends BaseMwmFragment implements OnBackPressLis
|
|||
{
|
||||
if (!mDelegate.onBackPressed())
|
||||
{
|
||||
((HelpActivity) requireActivity()).stackFragment(HelpFragment.class, getString(R.string.help), null);
|
||||
// ((HelpActivity) requireActivity()).stackFragment(HelpFragment.class, getString(R.string.help), null);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
package app.organicmaps.help;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import app.organicmaps.base.BaseToolbarActivity;
|
||||
|
||||
public class HelpActivity extends BaseToolbarActivity
|
||||
{
|
||||
@Override
|
||||
protected Class<? extends Fragment> getFragmentClass()
|
||||
{
|
||||
return HelpFragment.class;
|
||||
}
|
||||
}
|
100
android/src/app/organicmaps/help/HelpActivity.kt
Normal file
100
android/src/app/organicmaps/help/HelpActivity.kt
Normal file
|
@ -0,0 +1,100 @@
|
|||
package app.organicmaps.help
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import android.os.Bundle
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import app.organicmaps.R
|
||||
import app.organicmaps.util.Theme
|
||||
|
||||
class HelpActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContent {
|
||||
HelpContent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HelpContent() {
|
||||
val context = LocalContext.current
|
||||
Theme {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
stringResource(id = R.string.about_menu_title)
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(onClick = { (context as Activity).finish() }) {
|
||||
Icon(
|
||||
Icons.Filled.ArrowBack,
|
||||
contentDescription = stringResource(id = R.string.back)
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
) { contentPadding ->
|
||||
Box(
|
||||
Modifier
|
||||
.padding(contentPadding)
|
||||
.verticalScroll(
|
||||
rememberScrollState()
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(dimensionResource(id = R.dimen.margin_base))
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(dimensionResource(id = R.dimen.margin_base)))
|
||||
HelpHeader()
|
||||
HelpItemList(Modifier.padding(top = dimensionResource(id = R.dimen.margin_half)))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(
|
||||
name = "dark theme",
|
||||
uiMode = UI_MODE_NIGHT_YES
|
||||
)
|
||||
@Preview(name = "light theme")
|
||||
@Preview(
|
||||
name = "landscape",
|
||||
device = "spec:width=700dp,height=300dp,dpi=480,orientation=landscape"
|
||||
)
|
||||
annotation class HelpPreviews
|
||||
|
||||
@HelpPreviews
|
||||
@Composable
|
||||
private fun HelpPreview() {
|
||||
HelpContent()
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
package app.organicmaps.help;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.organicmaps.BuildConfig;
|
||||
import app.organicmaps.Framework;
|
||||
import app.organicmaps.R;
|
||||
import app.organicmaps.base.BaseMwmFragment;
|
||||
import app.organicmaps.util.Config;
|
||||
import app.organicmaps.util.Constants;
|
||||
import app.organicmaps.util.DateUtils;
|
||||
import app.organicmaps.util.Graphics;
|
||||
import app.organicmaps.util.Utils;
|
||||
|
||||
public class HelpFragment extends BaseMwmFragment implements View.OnClickListener
|
||||
{
|
||||
private String mDonateUrl;
|
||||
|
||||
private TextView setupItem(@IdRes int id, boolean tint, @NonNull View frame)
|
||||
{
|
||||
final TextView view = frame.findViewById(id);
|
||||
view.setOnClickListener(this);
|
||||
if (tint)
|
||||
Graphics.tint(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
|
||||
{
|
||||
mDonateUrl = Config.getDonateUrl();
|
||||
if (TextUtils.isEmpty(mDonateUrl) && !BuildConfig.FLAVOR.equals("google") && !BuildConfig.FLAVOR.equals("huawei"))
|
||||
mDonateUrl = getResources().getString(R.string.translated_om_site_url) + "donate/";
|
||||
|
||||
View root = inflater.inflate(R.layout.about, container, false);
|
||||
|
||||
((TextView) root.findViewById(R.id.version))
|
||||
.setText(BuildConfig.VERSION_NAME);
|
||||
|
||||
final boolean isLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||
|
||||
final String dataVersion = DateUtils.getShortDateFormatter().format(Framework.getDataVersion());
|
||||
final TextView dataVersionView = (TextView) root.findViewById(R.id.data_version);
|
||||
if (dataVersionView != null)
|
||||
dataVersionView.setText(getString(R.string.data_version, dataVersion));
|
||||
final TextView osmPresentationView = (TextView) root.findViewById(R.id.osm_presentation);
|
||||
if (osmPresentationView != null)
|
||||
osmPresentationView.setText(getString(R.string.osm_presentation, dataVersion));
|
||||
|
||||
setupItem(R.id.news, true, root);
|
||||
setupItem(R.id.web, true, root);
|
||||
setupItem(R.id.email, true, root);
|
||||
setupItem(R.id.github, true, root);
|
||||
setupItem(R.id.telegram, false, root);
|
||||
setupItem(R.id.instagram, false, root);
|
||||
setupItem(R.id.facebook, false, root);
|
||||
setupItem(R.id.twitter, true, root);
|
||||
setupItem(R.id.matrix, true, root);
|
||||
setupItem(R.id.mastodon, false, root);
|
||||
setupItem(R.id.openstreetmap, true, root);
|
||||
setupItem(R.id.faq, true, root);
|
||||
setupItem(R.id.report, isLandscape, root);
|
||||
|
||||
final TextView supportUsView = root.findViewById(R.id.support_us);
|
||||
if (BuildConfig.FLAVOR.equals("google") && !TextUtils.isEmpty(mDonateUrl))
|
||||
supportUsView.setVisibility(View.GONE);
|
||||
else
|
||||
setupItem(R.id.support_us, true, root);
|
||||
|
||||
final TextView donateView = root.findViewById(R.id.donate);
|
||||
if (TextUtils.isEmpty(mDonateUrl))
|
||||
donateView.setVisibility(View.GONE);
|
||||
else
|
||||
setupItem(R.id.donate, isLandscape, root);
|
||||
|
||||
if (BuildConfig.REVIEW_URL.isEmpty())
|
||||
root.findViewById(R.id.rate).setVisibility(View.GONE);
|
||||
else
|
||||
setupItem(R.id.rate, true, root);
|
||||
|
||||
setupItem(R.id.copyright, false, root);
|
||||
View termOfUseView = root.findViewById(R.id.term_of_use_link);
|
||||
View privacyPolicyView = root.findViewById(R.id.privacy_policy);
|
||||
termOfUseView.setOnClickListener(v -> onTermOfUseClick());
|
||||
privacyPolicyView.setOnClickListener(v -> onPrivacyPolicyClick());
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void openLink(@NonNull String link)
|
||||
{
|
||||
Utils.openUrl(requireActivity(), link);
|
||||
}
|
||||
|
||||
private void onPrivacyPolicyClick()
|
||||
{
|
||||
openLink(getResources().getString(R.string.translated_om_site_url) + "privacy/");
|
||||
}
|
||||
|
||||
private void onTermOfUseClick()
|
||||
{
|
||||
openLink(getResources().getString(R.string.translated_om_site_url) + "terms/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
final int id = v.getId();
|
||||
if (id == R.id.web)
|
||||
openLink(getResources().getString(R.string.translated_om_site_url));
|
||||
else if (id == R.id.news)
|
||||
openLink(getResources().getString(R.string.translated_om_site_url) + "news/");
|
||||
else if (id == R.id.email)
|
||||
Utils.sendTo(requireContext(), BuildConfig.SUPPORT_MAIL, "Organic Maps");
|
||||
else if (id == R.id.github)
|
||||
openLink(Constants.Url.GITHUB);
|
||||
else if (id == R.id.telegram)
|
||||
openLink(getString(R.string.telegram_url));
|
||||
else if (id == R.id.instagram)
|
||||
openLink(getString(R.string.instagram_url));
|
||||
else if (id == R.id.facebook)
|
||||
Utils.showFacebookPage(requireActivity());
|
||||
else if (id == R.id.twitter)
|
||||
openLink(Constants.Url.TWITTER);
|
||||
else if (id == R.id.matrix)
|
||||
openLink(Constants.Url.MATRIX);
|
||||
else if (id == R.id.mastodon)
|
||||
openLink(Constants.Url.MASTODON);
|
||||
else if (id == R.id.openstreetmap)
|
||||
openLink(getString(R.string.osm_wiki_about_url));
|
||||
else if (id == R.id.faq)
|
||||
((HelpActivity) requireActivity()).stackFragment(FaqFragment.class, getString(R.string.faq), null);
|
||||
else if (id == R.id.report)
|
||||
Utils.sendBugReport(requireActivity(), "");
|
||||
else if (id == R.id.support_us)
|
||||
openLink(getResources().getString(R.string.translated_om_site_url) + "support-us/");
|
||||
else if (id == R.id.donate)
|
||||
openLink(mDonateUrl);
|
||||
else if (id == R.id.rate)
|
||||
Utils.openAppInMarket(requireActivity(), BuildConfig.REVIEW_URL);
|
||||
else if (id == R.id.copyright)
|
||||
((HelpActivity) requireActivity()).stackFragment(CopyrightFragment.class, getString(R.string.copyright), null);
|
||||
}
|
||||
}
|
165
android/src/app/organicmaps/help/HelpHeader.kt
Normal file
165
android/src/app/organicmaps/help/HelpHeader.kt
Normal file
|
@ -0,0 +1,165 @@
|
|||
package app.organicmaps.help
|
||||
|
||||
import android.app.Activity
|
||||
import android.text.TextUtils
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.OutlinedButton
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.organicmaps.BuildConfig
|
||||
import app.organicmaps.Framework
|
||||
import app.organicmaps.R
|
||||
import app.organicmaps.util.Config
|
||||
import app.organicmaps.util.DateUtils
|
||||
import app.organicmaps.util.ExtendedMaterialTheme
|
||||
import app.organicmaps.util.Theme
|
||||
import app.organicmaps.util.Utils
|
||||
|
||||
@Composable
|
||||
fun HelpHeader() {
|
||||
BoxWithConstraints {
|
||||
if (maxWidth < 400.dp) {
|
||||
Column {
|
||||
HelpHeaderLeft()
|
||||
HelpHeaderRight()
|
||||
}
|
||||
} else {
|
||||
Row {
|
||||
HelpHeaderLeft(Modifier.weight(1f))
|
||||
HelpHeaderRight(Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HelpHeaderLeft(modifier: Modifier = Modifier) {
|
||||
Column(modifier, horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.logo),
|
||||
contentDescription = stringResource(id = R.string.app_name),
|
||||
tint = ExtendedMaterialTheme.colors.colorLogo,
|
||||
modifier = Modifier
|
||||
.size(96.dp)
|
||||
)
|
||||
SelectionContainer {
|
||||
Text(
|
||||
BuildConfig.VERSION_NAME,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = dimensionResource(id = R.dimen.margin_half)),
|
||||
textAlign = TextAlign.Center,
|
||||
style = ExtendedMaterialTheme.typography.caption
|
||||
)
|
||||
}
|
||||
Text(
|
||||
stringResource(id = R.string.about_headline),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = dimensionResource(id = R.dimen.margin_base)),
|
||||
textAlign = TextAlign.Center,
|
||||
style = ExtendedMaterialTheme.typography.h6
|
||||
)
|
||||
|
||||
Text(
|
||||
stringResource(id = R.string.about_proposition_1),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = dimensionResource(id = R.dimen.margin_half)),
|
||||
)
|
||||
Text(
|
||||
stringResource(id = R.string.about_proposition_2),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = dimensionResource(id = R.dimen.margin_half)),
|
||||
)
|
||||
Text(
|
||||
stringResource(id = R.string.about_proposition_3),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = dimensionResource(id = R.dimen.margin_half)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HelpHeaderRight(modifier: Modifier = Modifier) {
|
||||
val context = LocalContext.current
|
||||
val omWebsite = stringResource(id = R.string.translated_om_site_url)
|
||||
// Do not read the config while in the preview
|
||||
var donateUrl = if (!LocalInspectionMode.current) Config.getDonateUrl() else ""
|
||||
if (TextUtils.isEmpty(donateUrl) && BuildConfig.FLAVOR != "google" && BuildConfig.FLAVOR != "huawei")
|
||||
donateUrl = omWebsite + "donate/"
|
||||
|
||||
val dataVersion = if (!LocalInspectionMode.current) DateUtils.getShortDateFormatter()
|
||||
.format(Framework.getDataVersion()) else "DATA_VERSION"
|
||||
|
||||
Column(modifier) {
|
||||
Text(
|
||||
stringResource(id = R.string.about_developed_by_enthusiasts),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = dimensionResource(id = R.dimen.margin_half)),
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.ic_openstreetmap_color),
|
||||
contentDescription = stringResource(id = R.string.openstreetmap),
|
||||
modifier = Modifier
|
||||
.size(dimensionResource(id = R.dimen.osm_logo))
|
||||
)
|
||||
Text(
|
||||
stringResource(id = R.string.osm_presentation, dataVersion),
|
||||
modifier = Modifier.padding(start = dimensionResource(id = R.dimen.margin_half)),
|
||||
)
|
||||
}
|
||||
Button(
|
||||
onClick = { Utils.openUrl(context, donateUrl) },
|
||||
colors = ButtonDefaults.buttonColors(backgroundColor = ExtendedMaterialTheme.colors.material.secondary),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = dimensionResource(id = R.dimen.margin_half))
|
||||
) {
|
||||
Text(stringResource(id = R.string.donate))
|
||||
}
|
||||
OutlinedButton(
|
||||
onClick = { Utils.sendBugReport(context as Activity, "") },
|
||||
colors = ButtonDefaults.buttonColors(backgroundColor = ExtendedMaterialTheme.colors.material.surface),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(stringResource(id = R.string.report_a_bug))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@HelpPreviews
|
||||
@Composable
|
||||
private fun HelpHeaderPreview() {
|
||||
Theme {
|
||||
Surface {
|
||||
HelpHeader()
|
||||
}
|
||||
}
|
||||
}
|
232
android/src/app/organicmaps/help/HelpItemList.kt
Normal file
232
android/src/app/organicmaps/help/HelpItemList.kt
Normal file
|
@ -0,0 +1,232 @@
|
|||
package app.organicmaps.help
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.organicmaps.BuildConfig
|
||||
import app.organicmaps.R
|
||||
import app.organicmaps.util.Constants
|
||||
import app.organicmaps.util.ExtendedMaterialTheme
|
||||
import app.organicmaps.util.Theme
|
||||
import app.organicmaps.util.Utils
|
||||
|
||||
@Composable
|
||||
fun HelpItemList(modifier: Modifier = Modifier) {
|
||||
val context = LocalContext.current
|
||||
val omWebsite = stringResource(id = R.string.translated_om_site_url)
|
||||
|
||||
fun openUrl(url: String) {
|
||||
Utils.openUrl(context, url)
|
||||
}
|
||||
Column(modifier) {
|
||||
BoxWithConstraints {
|
||||
if (maxWidth < 400.dp) {
|
||||
Column {
|
||||
HelpItemsLeft()
|
||||
HelpItemsRight()
|
||||
}
|
||||
} else {
|
||||
Row {
|
||||
HelpItemsLeft(Modifier.weight(1f))
|
||||
HelpItemsRight(Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
}
|
||||
Divider()
|
||||
HelpItem(
|
||||
text = stringResource(id = R.string.privacy_policy),
|
||||
onClick = { openUrl(omWebsite + "privacy/") }
|
||||
)
|
||||
HelpItem(
|
||||
text = stringResource(id = R.string.terms_of_use),
|
||||
onClick = { openUrl(omWebsite + "terms/") }
|
||||
)
|
||||
HelpItem(
|
||||
text = stringResource(id = R.string.copyright),
|
||||
onClick = {} // TODO migrate that screen to compose as well
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HelpItemsLeft(modifier: Modifier = Modifier) {
|
||||
val context = LocalContext.current
|
||||
val omWebsite = stringResource(id = R.string.translated_om_site_url)
|
||||
val telegram = stringResource(id = R.string.telegram_url)
|
||||
|
||||
fun openUrl(url: String) {
|
||||
Utils.openUrl(context, url)
|
||||
}
|
||||
Column(modifier) {
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_donate),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.how_to_support_us),
|
||||
onClick = { Utils.openUrl(context, omWebsite + "support-us/") },
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_question_mark),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.faq),
|
||||
onClick = {} // TODO migrate that screen to compose as well
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_news),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.news),
|
||||
onClick = { openUrl(omWebsite + "news/") },
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_rate),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.rate_the_app),
|
||||
onClick = { Utils.openAppInMarket(context as Activity, BuildConfig.REVIEW_URL) },
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_telegram),
|
||||
text = stringResource(id = R.string.telegram),
|
||||
onClick = { openUrl(telegram) }
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_github),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.github),
|
||||
onClick = { openUrl(Constants.Url.GITHUB) }
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_website),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.website),
|
||||
onClick = { openUrl(omWebsite) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun HelpItemsRight(modifier: Modifier = Modifier) {
|
||||
val context = LocalContext.current
|
||||
val instagram = stringResource(id = R.string.instagram_url)
|
||||
val osm = stringResource(id = R.string.osm_wiki_about_url)
|
||||
|
||||
fun openUrl(url: String) {
|
||||
Utils.openUrl(context, url)
|
||||
}
|
||||
Column(modifier) {
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_email),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.email),
|
||||
onClick = { Utils.sendTo(context, BuildConfig.SUPPORT_MAIL, "Organic Maps") }
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_matrix),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.matrix),
|
||||
onClick = { openUrl(Constants.Url.MATRIX) }
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_mastodon),
|
||||
text = stringResource(id = R.string.mastodon),
|
||||
onClick = { openUrl(Constants.Url.MASTODON) }
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_facebook),
|
||||
text = stringResource(id = R.string.facebook),
|
||||
onClick = { Utils.showFacebookPage(context as Activity) }
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_twitterx),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.twitter),
|
||||
onClick = { openUrl(Constants.Url.TWITTER) }
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_instagram),
|
||||
text = stringResource(id = R.string.instagram),
|
||||
onClick = { openUrl(instagram) }
|
||||
)
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_openstreetmap),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.openstreetmap),
|
||||
onClick = { openUrl(osm) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun HelpItem(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
icon: Painter? = null,
|
||||
tintIcon: Boolean = false,
|
||||
onClick: () -> Unit = {},
|
||||
) {
|
||||
Box(modifier.clickable { onClick() }) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.height(dimensionResource(id = R.dimen.height_item_oneline))
|
||||
.padding(horizontal = dimensionResource(id = R.dimen.margin_base))
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
if (icon != null) Image(
|
||||
icon, contentDescription = "",
|
||||
colorFilter = if (tintIcon) ColorFilter.tint(ExtendedMaterialTheme.colors.iconTint) else null
|
||||
)
|
||||
Text(
|
||||
text,
|
||||
modifier = if (icon != null) Modifier.padding(start = dimensionResource(id = R.dimen.margin_base_plus)) else Modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun HelpItemPreview() {
|
||||
Theme {
|
||||
Surface {
|
||||
HelpItem(
|
||||
icon = painterResource(id = R.drawable.ic_openstreetmap),
|
||||
tintIcon = true,
|
||||
text = stringResource(id = R.string.openstreetmap),
|
||||
onClick = { /* Nothing */ }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@HelpPreviews
|
||||
@Composable
|
||||
private fun HelpHeaderPreview() {
|
||||
Theme {
|
||||
Surface {
|
||||
HelpItemList()
|
||||
}
|
||||
}
|
||||
}
|
21
android/src/app/organicmaps/util/Colors.kt
Normal file
21
android/src/app/organicmaps/util/Colors.kt
Normal file
|
@ -0,0 +1,21 @@
|
|||
package app.organicmaps.util
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
// Light theme
|
||||
val color_primary = Color(0xFF006C35)
|
||||
val color_on_primary = Color(0xFFFFFFFF)
|
||||
val color_secondary = Color(0xFF249CF2)
|
||||
val color_on_secondary = Color(0xFFFFFFFF)
|
||||
val color_icon_tint = Color(0x8A000000)
|
||||
val color_logo = color_primary
|
||||
val color_status_bar = color_primary
|
||||
|
||||
// Dark theme
|
||||
val color_primary_dark = Color(0xFF1E2226)
|
||||
val color_on_primary_dark = Color(0xFF000000)
|
||||
val color_secondary_dark = Color(0xFF4BB9E6)
|
||||
val color_on_secondary_dark = Color(0xFF000000)
|
||||
val color_icon_tint_dark = Color(0xB3FFFFFF)
|
||||
val color_logo_dark = Color(0xFFFFFFFF)
|
||||
val color_status_bar_dark = Color(0xFF272727)
|
113
android/src/app/organicmaps/util/Theme.kt
Normal file
113
android/src/app/organicmaps/util/Theme.kt
Normal file
|
@ -0,0 +1,113 @@
|
|||
package app.organicmaps.util
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material.Colors
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Shapes
|
||||
import androidx.compose.material.Typography
|
||||
import androidx.compose.material.darkColors
|
||||
import androidx.compose.material.lightColors
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
|
||||
// **********************************
|
||||
// Overwrite material theme colors
|
||||
// **********************************
|
||||
private val LightColors = lightColors(
|
||||
primary = color_primary,
|
||||
onPrimary = color_on_primary,
|
||||
secondary = color_secondary,
|
||||
onSecondary = color_on_secondary,
|
||||
)
|
||||
private val DarkColors = darkColors(
|
||||
primary = color_primary_dark,
|
||||
onPrimary = color_on_primary_dark,
|
||||
secondary = color_secondary_dark,
|
||||
onSecondary = color_on_secondary_dark,
|
||||
)
|
||||
|
||||
// **********************************
|
||||
// Define new theme colors
|
||||
// **********************************
|
||||
|
||||
// Defines a new class to hold material colors along with new ones
|
||||
// This is only to define the type, for the values see below
|
||||
@Immutable
|
||||
data class ExtendedColors(
|
||||
val material: Colors = LightColors,
|
||||
val iconTint: Color = Color.Unspecified,
|
||||
val colorLogo: Color = Color.Unspecified,
|
||||
val statusBar: Color = Color.Unspecified,
|
||||
)
|
||||
|
||||
// Define the value for the new colors
|
||||
private val LightExtendedColors = ExtendedColors(
|
||||
material = LightColors,
|
||||
iconTint = color_icon_tint,
|
||||
colorLogo = color_logo,
|
||||
statusBar = color_status_bar
|
||||
)
|
||||
private val DarkExtendedColors = ExtendedColors(
|
||||
material = DarkColors,
|
||||
iconTint = color_icon_tint_dark,
|
||||
colorLogo = color_logo_dark,
|
||||
statusBar = color_status_bar_dark
|
||||
)
|
||||
|
||||
val LocalExtendedColors = staticCompositionLocalOf {
|
||||
ExtendedColors()
|
||||
}
|
||||
|
||||
// Create a new theme object extending the material theme with our own colors
|
||||
// We can use this object to access our custom colors or default Material properties
|
||||
object ExtendedMaterialTheme {
|
||||
val colors: ExtendedColors
|
||||
@Composable
|
||||
get() = LocalExtendedColors.current
|
||||
val shapes: Shapes
|
||||
@Composable
|
||||
get() = MaterialTheme.shapes
|
||||
val typography: Typography
|
||||
@Composable
|
||||
get() = MaterialTheme.typography
|
||||
}
|
||||
|
||||
|
||||
// **********************************
|
||||
// Create the actual theme composable
|
||||
// **********************************
|
||||
@Composable
|
||||
fun Theme(
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
// Do not use ThemeUtils if the component is running in a preview window
|
||||
val nightMode = if (LocalInspectionMode.current)
|
||||
isSystemInDarkTheme()
|
||||
else
|
||||
ThemeUtils.isNightTheme(LocalContext.current)
|
||||
|
||||
val systemUiController = rememberSystemUiController()
|
||||
// Return our extended theme for use in our custom components
|
||||
CompositionLocalProvider(LocalExtendedColors provides if (nightMode) DarkExtendedColors else LightExtendedColors) {
|
||||
val statusBarColor = ExtendedMaterialTheme.colors.statusBar
|
||||
DisposableEffect(systemUiController, statusBarColor) {
|
||||
systemUiController.setStatusBarColor(
|
||||
color = statusBarColor,
|
||||
darkIcons = false
|
||||
)
|
||||
onDispose {}
|
||||
}
|
||||
// Return MaterialTheme so base components can read our overwritten properties
|
||||
MaterialTheme(
|
||||
colors = LocalExtendedColors.current.material,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
Reference in a new issue