Migrate some more to Jetpack Compose + Material3
This commit is contained in:
parent
643345493e
commit
c7e54f21d9
26 changed files with 223 additions and 1005 deletions
|
@ -166,9 +166,9 @@ android.productFlavors.forEach { flavor ->
|
||||||
apply(plugin = "com.google.firebase.crashlytics")
|
apply(plugin = "com.google.firebase.crashlytics")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.android.billingclient:billing:5.1.0")
|
implementation("com.android.billingclient:billing:6.0.1")
|
||||||
implementation("com.google.android.play:core-ktx:1.8.1")
|
implementation("com.google.android.play:core-ktx:1.8.1")
|
||||||
implementation("com.google.firebase:firebase-crashlytics:18.3.5")
|
implementation("com.google.firebase:firebase-crashlytics:18.4.1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package com.wbrawner.simplemarkdown.utility
|
package com.wbrawner.simplemarkdown.utility
|
||||||
|
|
||||||
import android.app.Activity
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.google.android.material.button.MaterialButton
|
|
||||||
|
|
||||||
class SupportLinkProvider(@Suppress("unused") private val activity: Activity) {
|
@Composable
|
||||||
val supportLinks = MutableLiveData<List<MaterialButton>>()
|
fun SupportLinks() {}
|
||||||
}
|
|
|
@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.pager.HorizontalPager
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.filled.Menu
|
import androidx.compose.material.icons.filled.Menu
|
||||||
|
@ -26,6 +27,7 @@ import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.NavigationDrawerItem
|
import androidx.compose.material3.NavigationDrawerItem
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Tab
|
import androidx.compose.material3.Tab
|
||||||
|
@ -42,9 +44,13 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontFamily
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
@ -101,7 +107,9 @@ fun MainScreen(navController: NavController, viewModel: MarkdownViewModel) {
|
||||||
DropdownMenuItem(text = {
|
DropdownMenuItem(text = {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("Lock Swiping")
|
Text("Lock Swiping")
|
||||||
Checkbox(checked = lockSwiping, onCheckedChange = { lockSwiping = !lockSwiping })
|
Checkbox(
|
||||||
|
checked = lockSwiping,
|
||||||
|
onCheckedChange = { lockSwiping = !lockSwiping })
|
||||||
}
|
}
|
||||||
}, onClick = {
|
}, onClick = {
|
||||||
lockSwiping = !lockSwiping
|
lockSwiping = !lockSwiping
|
||||||
|
@ -138,7 +146,9 @@ fun MainScreen(navController: NavController, viewModel: MarkdownViewModel) {
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
value = markdown,
|
value = markdown,
|
||||||
onValueChange = { viewModel.updateMarkdown(it) },
|
onValueChange = { viewModel.updateMarkdown(it) },
|
||||||
textStyle = TextStyle.Default.copy(fontFamily = FontFamily.Monospace)
|
textStyle = TextStyle.Default.copy(fontFamily = FontFamily.Monospace, color = MaterialTheme.colorScheme.onSurface),
|
||||||
|
keyboardOptions = KeyboardOptions(capitalization = KeyboardCapitalization.Sentences),
|
||||||
|
cursorBrush = SolidColor(MaterialTheme.colorScheme.onSurface)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
MarkdownPreview(modifier = Modifier.fillMaxSize(), markdown)
|
MarkdownPreview(modifier = Modifier.fillMaxSize(), markdown)
|
||||||
|
@ -154,18 +164,26 @@ fun MarkdownNavigationDrawer(
|
||||||
navigate: (Route) -> Unit, content: @Composable (drawerState: DrawerState) -> Unit
|
navigate: (Route) -> Unit, content: @Composable (drawerState: DrawerState) -> Unit
|
||||||
) {
|
) {
|
||||||
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
DismissibleNavigationDrawer(drawerState = drawerState, drawerContent = {
|
DismissibleNavigationDrawer(drawerState = drawerState, drawerContent = {
|
||||||
DismissibleDrawerSheet {
|
DismissibleDrawerSheet {
|
||||||
Route.entries.forEach { route ->
|
Route.entries.forEach { route ->
|
||||||
if (route == Route.EDITOR) {
|
if (route == Route.EDITOR) {
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
NavigationDrawerItem(icon = {
|
NavigationDrawerItem(
|
||||||
|
icon = {
|
||||||
Icon(imageVector = route.icon, contentDescription = null)
|
Icon(imageVector = route.icon, contentDescription = null)
|
||||||
},
|
},
|
||||||
label = { Text(route.title) },
|
label = { Text(route.title) },
|
||||||
selected = false,
|
selected = false,
|
||||||
onClick = { navigate(route) })
|
onClick = {
|
||||||
|
navigate(route)
|
||||||
|
coroutineScope.launch {
|
||||||
|
drawerState.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -14,7 +14,6 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.wbrawner.simplemarkdown.utility.readAssetToString
|
import com.wbrawner.simplemarkdown.utility.readAssetToString
|
||||||
import com.wbrawner.simplemarkdown.utility.toHtml
|
import com.wbrawner.simplemarkdown.utility.toHtml
|
||||||
import com.wbrawner.simplemarkdown.viewmodel.MarkdownViewModel
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MarkdownInfoScreen(
|
fun MarkdownInfoScreen(
|
||||||
|
|
|
@ -1,2 +1,104 @@
|
||||||
package com.wbrawner.simplemarkdown.ui
|
package com.wbrawner.simplemarkdown.ui
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
|
import androidx.browser.customtabs.CustomTabsIntent.SHARE_STATE_ON
|
||||||
|
import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Favorite
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.wbrawner.simplemarkdown.R
|
||||||
|
import com.wbrawner.simplemarkdown.utility.SupportLinks
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SupportScreen(navController: NavController) {
|
||||||
|
Scaffold(topBar = {
|
||||||
|
MarkdownTopAppBar(title = "Support SimpleMarkdown", navController = navController)
|
||||||
|
}) { paddingValues ->
|
||||||
|
val context = LocalContext.current
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp)
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
|
verticalArrangement = spacedBy(8.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier.size(100.dp),
|
||||||
|
imageVector = Icons.Default.Favorite,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
Text(context.getString(R.string.support_info), textAlign = TextAlign.Center)
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
Button(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
onClick = {
|
||||||
|
CustomTabsIntent.Builder()
|
||||||
|
.setShareState(SHARE_STATE_ON)
|
||||||
|
.build()
|
||||||
|
.launchUrl(context, Uri.parse("https://github.com/wbrawner/SimpleMarkdown"))
|
||||||
|
},
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = Color(context.getColor(R.color.colorBackgroundGitHub)),
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(context.getString(R.string.action_view_github))
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
onClick = {
|
||||||
|
val playStoreIntent = Intent(Intent.ACTION_VIEW)
|
||||||
|
.apply {
|
||||||
|
data = Uri.parse("market://details?id=${context.packageName}")
|
||||||
|
addFlags(
|
||||||
|
Intent.FLAG_ACTIVITY_NO_HISTORY or
|
||||||
|
Intent.FLAG_ACTIVITY_NEW_DOCUMENT or
|
||||||
|
Intent.FLAG_ACTIVITY_MULTIPLE_TASK
|
||||||
|
)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
startActivity(context, playStoreIntent, null)
|
||||||
|
} catch (ignored: ActivityNotFoundException) {
|
||||||
|
playStoreIntent.data =
|
||||||
|
Uri.parse("https://play.google.com/store/apps/details?id=${context.packageName}")
|
||||||
|
startActivity(context, playStoreIntent, null)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = Color(context.getColor(R.color.colorBackgroundPlayStore)),
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(context.getString(R.string.action_rate))
|
||||||
|
}
|
||||||
|
SupportLinks()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,28 +0,0 @@
|
||||||
package com.wbrawner.simplemarkdown.view
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Context
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.MotionEvent
|
|
||||||
import androidx.viewpager.widget.ViewPager
|
|
||||||
|
|
||||||
class DisableableViewPager : ViewPager {
|
|
||||||
private var isSwipeLocked = false
|
|
||||||
|
|
||||||
constructor(context: Context) : super(context)
|
|
||||||
|
|
||||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
|
||||||
|
|
||||||
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
|
|
||||||
return !isSwipeLocked && super.onInterceptTouchEvent(ev)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
|
||||||
override fun onTouchEvent(ev: MotionEvent): Boolean {
|
|
||||||
return !isSwipeLocked && super.onTouchEvent(ev)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSwipeLocked(locked: Boolean) {
|
|
||||||
this.isSwipeLocked = locked
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
package com.wbrawner.simplemarkdown.view
|
|
||||||
|
|
||||||
interface ViewPagerPage {
|
|
||||||
fun onSelected()
|
|
||||||
fun onDeselected()
|
|
||||||
}
|
|
|
@ -38,6 +38,7 @@ import com.wbrawner.simplemarkdown.R
|
||||||
import com.wbrawner.simplemarkdown.ui.MainScreen
|
import com.wbrawner.simplemarkdown.ui.MainScreen
|
||||||
import com.wbrawner.simplemarkdown.ui.MarkdownInfoScreen
|
import com.wbrawner.simplemarkdown.ui.MarkdownInfoScreen
|
||||||
import com.wbrawner.simplemarkdown.ui.SettingsScreen
|
import com.wbrawner.simplemarkdown.ui.SettingsScreen
|
||||||
|
import com.wbrawner.simplemarkdown.ui.SupportScreen
|
||||||
import com.wbrawner.simplemarkdown.ui.theme.SimpleMarkdownTheme
|
import com.wbrawner.simplemarkdown.ui.theme.SimpleMarkdownTheme
|
||||||
import com.wbrawner.simplemarkdown.viewmodel.MarkdownViewModel
|
import com.wbrawner.simplemarkdown.viewmodel.MarkdownViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -126,7 +127,7 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes
|
||||||
SettingsScreen(navController = navController)
|
SettingsScreen(navController = navController)
|
||||||
}
|
}
|
||||||
composable(Route.SUPPORT.path) {
|
composable(Route.SUPPORT.path) {
|
||||||
Text("To do")
|
SupportScreen(navController = navController)
|
||||||
}
|
}
|
||||||
composable(Route.HELP.path) {
|
composable(Route.HELP.path) {
|
||||||
MarkdownInfoScreen(title = Route.HELP.title, file = "Cheatsheet.md", navController = navController)
|
MarkdownInfoScreen(title = Route.HELP.title, file = "Cheatsheet.md", navController = navController)
|
||||||
|
@ -141,12 +142,6 @@ class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsRes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
|
||||||
if (!findNavController(R.id.content).navigateUp()) {
|
|
||||||
super.onBackPressed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Route(
|
enum class Route(
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
package com.wbrawner.simplemarkdown.view.adapter
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.FragmentManager
|
|
||||||
import androidx.fragment.app.FragmentPagerAdapter
|
|
||||||
import androidx.viewpager.widget.ViewPager
|
|
||||||
import com.wbrawner.simplemarkdown.R
|
|
||||||
import com.wbrawner.simplemarkdown.view.fragment.EditFragment
|
|
||||||
import com.wbrawner.simplemarkdown.view.fragment.PreviewFragment
|
|
||||||
|
|
||||||
class EditPagerAdapter(fm: FragmentManager, private val context: Context)
|
|
||||||
: FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT), ViewPager.OnPageChangeListener {
|
|
||||||
|
|
||||||
private val editFragment = EditFragment()
|
|
||||||
private val previewFragment = PreviewFragment()
|
|
||||||
|
|
||||||
override fun getItem(position: Int): Fragment {
|
|
||||||
return when (position) {
|
|
||||||
FRAGMENT_EDIT -> editFragment
|
|
||||||
FRAGMENT_PREVIEW -> previewFragment
|
|
||||||
else -> throw IllegalStateException("Attempting to get fragment for invalid page number")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getCount(): Int {
|
|
||||||
return NUM_PAGES
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPageTitle(position: Int): CharSequence? {
|
|
||||||
var stringId = 0
|
|
||||||
when (position) {
|
|
||||||
FRAGMENT_EDIT -> stringId = R.string.action_edit
|
|
||||||
FRAGMENT_PREVIEW -> stringId = R.string.action_preview
|
|
||||||
}
|
|
||||||
return context.getString(stringId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPageWidth(position: Int): Float {
|
|
||||||
return if (context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
|
||||||
0.5f
|
|
||||||
} else {
|
|
||||||
super.getPageWidth(position)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPageScrollStateChanged(state: Int) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPageSelected(position: Int) {
|
|
||||||
when (position) {
|
|
||||||
FRAGMENT_EDIT -> {
|
|
||||||
editFragment.onSelected()
|
|
||||||
}
|
|
||||||
FRAGMENT_PREVIEW -> {
|
|
||||||
editFragment.onDeselected()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val FRAGMENT_EDIT = 0
|
|
||||||
const val FRAGMENT_PREVIEW = 1
|
|
||||||
const val NUM_PAGES = 2
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
//package com.wbrawner.simplemarkdown.view.fragment
|
|
||||||
//
|
|
||||||
//import android.content.res.Configuration
|
|
||||||
//import android.os.Bundle
|
|
||||||
//import android.view.LayoutInflater
|
|
||||||
//import android.view.MenuItem
|
|
||||||
//import android.view.View
|
|
||||||
//import android.view.ViewGroup
|
|
||||||
//import android.widget.Toast
|
|
||||||
//import androidx.appcompat.app.AppCompatDelegate
|
|
||||||
//import androidx.fragment.app.Fragment
|
|
||||||
//import androidx.lifecycle.lifecycleScope
|
|
||||||
//import androidx.navigation.fragment.findNavController
|
|
||||||
//import androidx.navigation.ui.setupWithNavController
|
|
||||||
//import com.wbrawner.plausible.android.Plausible
|
|
||||||
//import com.wbrawner.simplemarkdown.R
|
|
||||||
//import com.wbrawner.simplemarkdown.databinding.FragmentMarkdownInfoBinding
|
|
||||||
//import com.wbrawner.simplemarkdown.utility.*
|
|
||||||
//import kotlinx.coroutines.launch
|
|
||||||
//
|
|
||||||
//class MarkdownInfoFragment : Fragment() {
|
|
||||||
// private val errorHandler: ErrorHandler by errorHandlerImpl()
|
|
||||||
// private var _binding: FragmentMarkdownInfoBinding? = null
|
|
||||||
// private val binding: FragmentMarkdownInfoBinding
|
|
||||||
// get() = _binding!!
|
|
||||||
//
|
|
||||||
// override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
// super.onCreate(savedInstanceState)
|
|
||||||
// setHasOptionsMenu(true)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
|
||||||
// _binding = FragmentMarkdownInfoBinding.inflate(inflater, container, false)
|
|
||||||
// return binding.root
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onDestroyView() {
|
|
||||||
// super.onDestroyView()
|
|
||||||
// _binding = null
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
// val fileName = arguments?.getString(EXTRA_FILE)
|
|
||||||
// if (fileName.isNullOrBlank()) {
|
|
||||||
// findNavController().navigateUp()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// binding.toolbar.setupWithNavController(findNavController())
|
|
||||||
//
|
|
||||||
// val isNightMode = AppCompatDelegate.getDefaultNightMode() ==
|
|
||||||
// AppCompatDelegate.MODE_NIGHT_YES
|
|
||||||
// || resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
|
||||||
// val defaultCssId = if (isNightMode) {
|
|
||||||
// R.string.pref_custom_css_default_dark
|
|
||||||
// } else {
|
|
||||||
// R.string.pref_custom_css_default
|
|
||||||
// }
|
|
||||||
// val css: String? = getString(defaultCssId)
|
|
||||||
// lifecycleScope.launch {
|
|
||||||
// try {
|
|
||||||
// val html = view.context.assets?.readAssetToString(fileName)
|
|
||||||
// ?.toHtml()
|
|
||||||
// ?: throw RuntimeException("Unable to open stream to $fileName")
|
|
||||||
// binding.infoWebview.loadDataWithBaseURL(null,
|
|
||||||
// String.format(FORMAT_CSS, css) + html,
|
|
||||||
// "text/html",
|
|
||||||
// "UTF-8", null
|
|
||||||
// )
|
|
||||||
// } catch (e: Exception) {
|
|
||||||
// errorHandler.reportException(e)
|
|
||||||
// Toast.makeText(view.context, R.string.file_load_error, Toast.LENGTH_SHORT).show()
|
|
||||||
// findNavController().navigateUp()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
// if (item.itemId == android.R.id.home) {
|
|
||||||
// findNavController().navigateUp()
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// return super.onOptionsItemSelected(item)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onStart() {
|
|
||||||
// super.onStart()
|
|
||||||
// arguments?.getString(EXTRA_FILE)?.let {
|
|
||||||
// Plausible.pageView(it)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// companion object {
|
|
||||||
// const val FORMAT_CSS = "<style>" +
|
|
||||||
// "%s" +
|
|
||||||
// "</style>"
|
|
||||||
// const val EXTRA_TITLE = "title"
|
|
||||||
// const val EXTRA_FILE = "file"
|
|
||||||
// }
|
|
||||||
//}
|
|
|
@ -1,45 +0,0 @@
|
||||||
//package com.wbrawner.simplemarkdown.view.fragment
|
|
||||||
//
|
|
||||||
//import android.os.Bundle
|
|
||||||
//import android.view.LayoutInflater
|
|
||||||
//import android.view.MenuItem
|
|
||||||
//import android.view.View
|
|
||||||
//import android.view.ViewGroup
|
|
||||||
//import androidx.fragment.app.Fragment
|
|
||||||
//import androidx.navigation.fragment.findNavController
|
|
||||||
//import androidx.navigation.ui.setupWithNavController
|
|
||||||
//import com.wbrawner.plausible.android.Plausible
|
|
||||||
//import com.wbrawner.simplemarkdown.R
|
|
||||||
//import com.wbrawner.simplemarkdown.databinding.FragmentSettingsBinding
|
|
||||||
//
|
|
||||||
//class SettingsContainerFragment : Fragment() {
|
|
||||||
// private var _binding: FragmentSettingsBinding? = null
|
|
||||||
// private val binding: FragmentSettingsBinding
|
|
||||||
// get() = _binding!!
|
|
||||||
//
|
|
||||||
// override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
// super.onCreate(savedInstanceState)
|
|
||||||
// setHasOptionsMenu(true)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
|
||||||
// _binding = FragmentSettingsBinding.inflate(inflater, container, false)
|
|
||||||
// return binding.root
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onDestroyView() {
|
|
||||||
// super.onDestroyView()
|
|
||||||
// _binding = null
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
// binding.toolbar.setupWithNavController(findNavController())
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onOptionsItemSelected(item: MenuItem): Boolean = findNavController().navigateUp()
|
|
||||||
//
|
|
||||||
// override fun onStart() {
|
|
||||||
// super.onStart()
|
|
||||||
// Plausible.pageView("Settings")
|
|
||||||
// }
|
|
||||||
//}
|
|
|
@ -1,82 +0,0 @@
|
||||||
package com.wbrawner.simplemarkdown.view.fragment
|
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.preference.ListPreference
|
|
||||||
import androidx.preference.Preference
|
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import com.wbrawner.simplemarkdown.BuildConfig
|
|
||||||
import com.wbrawner.simplemarkdown.R
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
class SettingsFragment
|
|
||||||
: PreferenceFragmentCompat(),
|
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
||||||
addPreferencesFromResource(R.xml.pref_general)
|
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
preferenceScreen.addPreference(Preference(preferenceScreen.context).apply {
|
|
||||||
title = "Force crash"
|
|
||||||
onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
|
||||||
throw RuntimeException("Forced crash from settings")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
|
||||||
super.onActivityCreated(savedInstanceState)
|
|
||||||
lifecycleScope.launch(context = Dispatchers.IO) {
|
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
|
||||||
sharedPreferences.registerOnSharedPreferenceChangeListener(this@SettingsFragment)
|
|
||||||
(findPreference(getString(R.string.pref_key_dark_mode)) as? ListPreference)?.let {
|
|
||||||
setListPreferenceSummary(sharedPreferences, it)
|
|
||||||
}
|
|
||||||
@Suppress("ConstantConditionIf")
|
|
||||||
if (!BuildConfig.ENABLE_CUSTOM_CSS) {
|
|
||||||
findPreference<Preference>(getString(R.string.pref_custom_css))?.let {
|
|
||||||
preferenceScreen.removePreference(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
|
||||||
if (!isAdded || sharedPreferences == null || key == null) return
|
|
||||||
val preference = findPreference(key) as? ListPreference ?: return
|
|
||||||
setListPreferenceSummary(sharedPreferences, preference)
|
|
||||||
if (preference.key != getString(R.string.pref_key_dark_mode)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var darkMode: Int = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
|
|
||||||
AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY
|
|
||||||
} else {
|
|
||||||
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
|
||||||
}
|
|
||||||
val darkModeValue = sharedPreferences.getString(preference.key, null)
|
|
||||||
if (!darkModeValue.isNullOrEmpty()) {
|
|
||||||
if (darkModeValue.equals(getString(R.string.pref_value_light), ignoreCase = true)) {
|
|
||||||
darkMode = AppCompatDelegate.MODE_NIGHT_NO
|
|
||||||
} else if (darkModeValue.equals(getString(R.string.pref_value_dark), ignoreCase = true)) {
|
|
||||||
darkMode = AppCompatDelegate.MODE_NIGHT_YES
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AppCompatDelegate.setDefaultNightMode(darkMode)
|
|
||||||
activity?.recreate()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setListPreferenceSummary(sharedPreferences: SharedPreferences, preference: ListPreference) {
|
|
||||||
val storedValue = sharedPreferences.getString(
|
|
||||||
preference.key,
|
|
||||||
null
|
|
||||||
) ?: return
|
|
||||||
val index = preference.findIndexOfValue(storedValue)
|
|
||||||
if (index < 0) return
|
|
||||||
preference.summary = preference.entries[index].toString()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
//package com.wbrawner.simplemarkdown.view.fragment
|
|
||||||
//
|
|
||||||
//import android.content.ActivityNotFoundException
|
|
||||||
//import android.content.Intent
|
|
||||||
//import android.net.Uri
|
|
||||||
//import android.os.Bundle
|
|
||||||
//import android.view.LayoutInflater
|
|
||||||
//import android.view.View
|
|
||||||
//import android.view.ViewGroup
|
|
||||||
//import androidx.browser.customtabs.CustomTabsIntent
|
|
||||||
//import androidx.fragment.app.Fragment
|
|
||||||
//import androidx.lifecycle.Observer
|
|
||||||
//import androidx.navigation.fragment.findNavController
|
|
||||||
//import androidx.navigation.ui.setupWithNavController
|
|
||||||
//import com.wbrawner.plausible.android.Plausible
|
|
||||||
//import com.wbrawner.simplemarkdown.databinding.FragmentSupportBinding
|
|
||||||
//import com.wbrawner.simplemarkdown.utility.SupportLinkProvider
|
|
||||||
//
|
|
||||||
//class SupportFragment : Fragment() {
|
|
||||||
// private var _binding: FragmentSupportBinding? = null
|
|
||||||
// private val binding: FragmentSupportBinding
|
|
||||||
// get() = _binding!!
|
|
||||||
//
|
|
||||||
// override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
|
||||||
// _binding = FragmentSupportBinding.inflate(inflater, container, false)
|
|
||||||
// return binding.root
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onDestroyView() {
|
|
||||||
// super.onDestroyView()
|
|
||||||
// _binding = null
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
// binding.toolbar.setupWithNavController(findNavController())
|
|
||||||
// binding.githubButton.setOnClickListener {
|
|
||||||
// CustomTabsIntent.Builder()
|
|
||||||
// .addDefaultShareMenuItem()
|
|
||||||
// .build()
|
|
||||||
// .launchUrl(view.context, Uri.parse("https://github" +
|
|
||||||
// ".com/wbrawner/SimpleMarkdown"))
|
|
||||||
// }
|
|
||||||
// binding.rateButton.setOnClickListener {
|
|
||||||
// val playStoreIntent = Intent(Intent.ACTION_VIEW)
|
|
||||||
// .apply {
|
|
||||||
// data = Uri.parse("market://details?id=${view.context.packageName}")
|
|
||||||
// addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY or
|
|
||||||
// Intent.FLAG_ACTIVITY_NEW_DOCUMENT or
|
|
||||||
// Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
|
|
||||||
// }
|
|
||||||
// try {
|
|
||||||
// startActivity(playStoreIntent)
|
|
||||||
// } catch (ignored: ActivityNotFoundException) {
|
|
||||||
// playStoreIntent.data = Uri.parse("https://play.google.com/store/apps/details?id=${view.context.packageName}")
|
|
||||||
// startActivity(playStoreIntent)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// SupportLinkProvider(requireActivity()).supportLinks.observe(viewLifecycleOwner, Observer { links ->
|
|
||||||
// links.forEach {
|
|
||||||
// binding.supportButtons.addView(it)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onStart() {
|
|
||||||
// super.onStart()
|
|
||||||
// Plausible.pageView("Support")
|
|
||||||
// }
|
|
||||||
//}
|
|
|
@ -1,61 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:id="@+id/drawerLayout">
|
|
||||||
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<com.wbrawner.simplemarkdown.view.DisableableViewPager
|
|
||||||
android:id="@+id/pager"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:id="@+id/bottomSheet"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:background="@color/colorBackground"
|
|
||||||
app:layout_scrollFlags="scroll|enterAlways" />
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
|
||||||
android:id="@+id/tabLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@color/colorBackground"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
|
||||||
android:id="@+id/editTab"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/action_edit" />
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
|
||||||
android:id="@+id/previewTab"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/action_preview" />
|
|
||||||
</com.google.android.material.tabs.TabLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.navigation.NavigationView
|
|
||||||
android:id="@+id/navigationView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
app:menu="@menu/menu_main" />
|
|
||||||
|
|
||||||
</androidx.drawerlayout.widget.DrawerLayout>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/content"
|
|
||||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:defaultNavHost="true"
|
|
||||||
app:navGraph="@navigation/nav_graph" />
|
|
|
@ -1,23 +0,0 @@
|
||||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/markdown_edit_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context="com.wbrawner.simplemarkdown.view.fragment.EditFragment">
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/markdown_edit"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@null"
|
|
||||||
android:gravity="top"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:hint="@string/markdown_here"
|
|
||||||
android:imeOptions="flagNoExtractUi"
|
|
||||||
android:inputType="textMultiLine|textCapSentences"
|
|
||||||
android:paddingLeft="8dp"
|
|
||||||
android:paddingRight="8dp"
|
|
||||||
android:paddingBottom="16dp"
|
|
||||||
android:scrollHorizontally="false"
|
|
||||||
android:importantForAutofill="no" />
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
|
@ -1,63 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@color/colorBackground"
|
|
||||||
android:id="@+id/drawerLayout">
|
|
||||||
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<com.wbrawner.simplemarkdown.view.DisableableViewPager
|
|
||||||
android:id="@+id/pager"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:id="@+id/bottomSheet"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:liftOnScroll="true">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:background="@color/colorBackground"
|
|
||||||
app:layout_scrollFlags="scroll|enterAlways|snap" />
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
|
||||||
android:id="@+id/tabLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom"
|
|
||||||
android:background="@color/colorBackground">
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
|
||||||
android:id="@+id/editTab"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/action_edit" />
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
|
||||||
android:id="@+id/previewTab"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/action_preview" />
|
|
||||||
</com.google.android.material.tabs.TabLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.navigation.NavigationView
|
|
||||||
android:id="@+id/navigationView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
app:menu="@menu/menu_main" />
|
|
||||||
|
|
||||||
</androidx.drawerlayout.widget.DrawerLayout>
|
|
|
@ -1,43 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
|
|
||||||
tools:context="com.wbrawner.simplemarkdown.view.fragment.MarkdownInfoFragment">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:id="@+id/appBarLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="128dp"
|
|
||||||
android:background="@color/colorBackground">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:elevation="0dp"
|
|
||||||
app:layout_collapseMode="pin" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<WebView
|
|
||||||
android:id="@+id/infoWebview"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:nestedScrollingEnabled="false" />
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
|
@ -1,13 +0,0 @@
|
||||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context="com.wbrawner.simplemarkdown.view.fragment.PreviewFragment">
|
|
||||||
|
|
||||||
<WebView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:nestedScrollingEnabled="false"
|
|
||||||
android:id="@+id/markdown_view" />
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:id="@+id/appBarLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:background="@color/colorBackground" />
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/fragment_settings"
|
|
||||||
android:name="com.wbrawner.simplemarkdown.view.fragment.SettingsFragment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
|
@ -1,78 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
android:background="@color/colorBackground"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:clipChildren="false"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:padding="16dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/toolbar">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/heartIcon"
|
|
||||||
android:layout_width="100dp"
|
|
||||||
android:layout_height="100dp"
|
|
||||||
android:src="@drawable/ic_favorite_black_24dp"
|
|
||||||
android:tint="@color/colorAccent"
|
|
||||||
android:contentDescription="@string/description_heart"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/supportInfoText"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:text="@string/support_info"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textColor="@color/colorOnBackground"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/heartIcon" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/githubButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:backgroundTint="@color/colorBackgroundGitHub"
|
|
||||||
android:textColor="@color/colorWhite"
|
|
||||||
android:text="@string/action_view_github"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/supportInfoText" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/rateButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:backgroundTint="@color/colorBackgroundPlayStore"
|
|
||||||
android:textColor="@color/colorWhite"
|
|
||||||
android:text="@string/action_rate"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/githubButton" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/supportButtons"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:orientation="vertical"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/rateButton" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -1,33 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_share"
|
|
||||||
android:icon="@drawable/ic_share"
|
|
||||||
android:title="@string/action_share"
|
|
||||||
app:showAsAction="ifRoom" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_new"
|
|
||||||
android:title="@string/action_new"
|
|
||||||
android:alphabeticShortcut="N"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_load"
|
|
||||||
android:title="@string/action_open"
|
|
||||||
android:alphabeticShortcut="O"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_save"
|
|
||||||
android:alphabeticShortcut="S"
|
|
||||||
android:title="@string/action_save" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_save_as"
|
|
||||||
android:title="@string/action_save_as"
|
|
||||||
tools:ignore="UnusedAttribute" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_lock_swipe"
|
|
||||||
android:checkable="true"
|
|
||||||
android:title="@string/action_lock_swipe"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
</menu>
|
|
|
@ -1,33 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
<group android:id="@+id/mainGroup">
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_mainFragment_to_settingsContainerFragment"
|
|
||||||
android:title="@string/action_settings"
|
|
||||||
android:icon="@drawable/ic_settings_black_24dp"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_mainFragment_to_supportFragment"
|
|
||||||
android:title="@string/support_title"
|
|
||||||
android:icon="@drawable/ic_favorite_black_24dp"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
</group>
|
|
||||||
<group android:id="@+id/addtionalInfoGroup">
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_mainFragment_to_helpFragment"
|
|
||||||
android:title="@string/action_help"
|
|
||||||
android:icon="@drawable/ic_help_black_24dp"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_mainFragment_to_librariesFragment"
|
|
||||||
android:title="@string/action_libraries"
|
|
||||||
android:icon="@drawable/ic_info_black_24dp"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_mainFragment_to_privacyFragment"
|
|
||||||
android:title="@string/action_privacy"
|
|
||||||
android:icon="@drawable/ic_eye_black_24dp"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
</group>
|
|
||||||
</menu>
|
|
|
@ -1,87 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<navigation 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:id="@+id/nav_graph"
|
|
||||||
app:startDestination="@+id/mainFragment">
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/settingsContainerFragment"
|
|
||||||
android:name="com.wbrawner.simplemarkdown.view.fragment.SettingsContainerFragment"
|
|
||||||
android:label="@string/title_activity_settings" />
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/mainFragment"
|
|
||||||
android:name="com.wbrawner.simplemarkdown.view.fragment.MainFragment"
|
|
||||||
android:label="">
|
|
||||||
<action
|
|
||||||
android:id="@+id/action_mainFragment_to_helpFragment"
|
|
||||||
app:destination="@id/helpFragment"
|
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popUpTo="@id/mainFragment" />
|
|
||||||
<action
|
|
||||||
android:id="@+id/action_mainFragment_to_privacyFragment"
|
|
||||||
app:destination="@id/privacyFragment"
|
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popUpTo="@id/mainFragment" />
|
|
||||||
<action
|
|
||||||
android:id="@+id/action_mainFragment_to_librariesFragment"
|
|
||||||
app:destination="@id/librariesFragment"
|
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popUpTo="@id/mainFragment" />
|
|
||||||
<action
|
|
||||||
android:id="@+id/action_mainFragment_to_settingsContainerFragment"
|
|
||||||
app:destination="@id/settingsContainerFragment"
|
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popUpTo="@id/mainFragment" />
|
|
||||||
<action
|
|
||||||
android:id="@+id/action_mainFragment_to_supportFragment"
|
|
||||||
app:destination="@id/supportFragment"
|
|
||||||
app:enterAnim="@anim/nav_default_enter_anim"
|
|
||||||
app:exitAnim="@anim/nav_default_exit_anim"
|
|
||||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
|
||||||
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
|
||||||
app:popUpTo="@id/mainFragment" />
|
|
||||||
</fragment>
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/supportFragment"
|
|
||||||
android:name="com.wbrawner.simplemarkdown.view.fragment.SupportFragment"
|
|
||||||
android:label="@string/support_title" />
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/helpFragment"
|
|
||||||
android:name="com.wbrawner.simplemarkdown.view.fragment.MarkdownInfoFragment"
|
|
||||||
android:label="@string/action_help"
|
|
||||||
tools:layout="@layout/fragment_markdown_info">
|
|
||||||
<argument
|
|
||||||
android:name="file"
|
|
||||||
app:argType="string"
|
|
||||||
android:defaultValue="Cheatsheet.md" />
|
|
||||||
</fragment>
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/privacyFragment"
|
|
||||||
android:name="com.wbrawner.simplemarkdown.view.fragment.MarkdownInfoFragment"
|
|
||||||
android:label="@string/action_privacy"
|
|
||||||
tools:layout="@layout/fragment_markdown_info">
|
|
||||||
<argument
|
|
||||||
android:name="file"
|
|
||||||
android:defaultValue="Privacy Policy.md"
|
|
||||||
app:argType="string" />
|
|
||||||
</fragment>
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/librariesFragment"
|
|
||||||
android:name="com.wbrawner.simplemarkdown.view.fragment.MarkdownInfoFragment"
|
|
||||||
android:label="@string/action_libraries"
|
|
||||||
tools:layout="@layout/fragment_markdown_info">
|
|
||||||
<argument
|
|
||||||
android:name="file"
|
|
||||||
android:defaultValue="Libraries.md"
|
|
||||||
app:argType="string" />
|
|
||||||
</fragment>
|
|
||||||
</navigation>
|
|
|
@ -1,27 +0,0 @@
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<SwitchPreference
|
|
||||||
android:defaultValue="true"
|
|
||||||
android:key="autosave"
|
|
||||||
android:summaryOff="@string/pref_autosave_off"
|
|
||||||
android:summaryOn="@string/pref_autosave_on"
|
|
||||||
android:title="@string/pref_title_autosave" />
|
|
||||||
<EditTextPreference
|
|
||||||
android:defaultValue="@string/pref_custom_css_default"
|
|
||||||
android:key="@string/pref_custom_css"
|
|
||||||
android:summary="@string/pref_description_custom_css"
|
|
||||||
android:title="@string/pref_title_custom_css" />
|
|
||||||
<ListPreference
|
|
||||||
android:entries="@array/pref_entries_dark_mode"
|
|
||||||
android:entryValues="@array/pref_values_dark_mode"
|
|
||||||
android:defaultValue="@string/pref_key_dark_mode_auto"
|
|
||||||
android:key="@string/pref_key_dark_mode"
|
|
||||||
android:title="@string/title_dark_mode" />
|
|
||||||
<SwitchPreference
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="@string/readability_enabled"
|
|
||||||
android:summaryOff="@string/pref_readability_off"
|
|
||||||
android:summaryOn="@string/pref_readability_on"
|
|
||||||
android:title="@string/pref_title_readability" />
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
|
|
@ -1,105 +1,107 @@
|
||||||
package com.wbrawner.simplemarkdown.utility
|
package com.wbrawner.simplemarkdown.utility
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.Application
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import com.android.billingclient.api.*
|
import androidx.compose.material3.Button
|
||||||
import com.google.android.material.button.MaterialButton
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import com.android.billingclient.api.BillingClient
|
||||||
|
import com.android.billingclient.api.BillingClientStateListener
|
||||||
|
import com.android.billingclient.api.BillingFlowParams
|
||||||
|
import com.android.billingclient.api.BillingFlowParams.ProductDetailsParams
|
||||||
|
import com.android.billingclient.api.BillingResult
|
||||||
|
import com.android.billingclient.api.ConsumeParams
|
||||||
|
import com.android.billingclient.api.ProductDetails
|
||||||
|
import com.android.billingclient.api.QueryProductDetailsParams
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
|
|
||||||
class SupportLinkProvider(private val activity: Activity) : BillingClientStateListener,
|
@Composable
|
||||||
PurchasesUpdatedListener {
|
fun SupportLinks() {
|
||||||
val supportLinks = MutableLiveData<List<MaterialButton>>()
|
val context = LocalContext.current
|
||||||
|
var products by remember { mutableStateOf(emptyList<ProductDetails>()) }
|
||||||
private val billingClient: BillingClient = BillingClient.newBuilder(activity.applicationContext)
|
var billingClient by remember { mutableStateOf<BillingClient?>(null) }
|
||||||
.setListener(this)
|
DisposableEffect(context) {
|
||||||
|
billingClient = BillingClient.newBuilder(context.applicationContext)
|
||||||
|
.setListener { _, purchases ->
|
||||||
|
purchases?.forEach { purchase ->
|
||||||
|
val consumeParams = ConsumeParams.newBuilder()
|
||||||
|
.setPurchaseToken(purchase.purchaseToken)
|
||||||
|
.build()
|
||||||
|
billingClient?.consumeAsync(consumeParams) { _, _ ->
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.support_thank_you),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.enablePendingPurchases()
|
.enablePendingPurchases()
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
init {
|
billingClient?.startConnection(object : BillingClientStateListener {
|
||||||
billingClient.startConnection(this)
|
override fun onBillingServiceDisconnected() {
|
||||||
activity.application.registerActivityLifecycleCallbacks(
|
billingClient?.startConnection(this)
|
||||||
object : Application.ActivityLifecycleCallbacks {
|
|
||||||
override fun onActivityPaused(activity: Activity) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityStarted(activity: Activity) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityDestroyed(activity: Activity) {
|
|
||||||
billingClient.endConnection()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityStopped(activity: Activity) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityResumed(activity: Activity) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBillingSetupFinished(result: BillingResult) {
|
override fun onBillingSetupFinished(result: BillingResult) {
|
||||||
if (result.responseCode != BillingClient.BillingResponseCode.OK) {
|
if (result.responseCode != BillingClient.BillingResponseCode.OK) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
val productsQuery = listOf("support_the_developer", "tip_coffee", "tip_beer")
|
||||||
val skuDetails = SkuDetailsParams.newBuilder()
|
.map {
|
||||||
.setSkusList(listOf("support_the_developer", "tip_coffee", "tip_beer"))
|
QueryProductDetailsParams.Product.newBuilder()
|
||||||
.setType(BillingClient.SkuType.INAPP)
|
.setProductId(it)
|
||||||
|
.setProductType(BillingClient.ProductType.INAPP)
|
||||||
.build()
|
.build()
|
||||||
billingClient.querySkuDetailsAsync(skuDetails) { skuDetailsResponse, skuDetailsList ->
|
}
|
||||||
// Process the result.
|
val productDetailsQuery = QueryProductDetailsParams.newBuilder()
|
||||||
if (skuDetailsResponse.responseCode != BillingClient.BillingResponseCode.OK || skuDetailsList.isNullOrEmpty()) {
|
.setProductList(productsQuery)
|
||||||
return@querySkuDetailsAsync
|
.build()
|
||||||
|
billingClient?.queryProductDetailsAsync(productDetailsQuery) { result, productDetails ->
|
||||||
|
if (result.responseCode != BillingClient.BillingResponseCode.OK || productDetails.isEmpty()) {
|
||||||
|
return@queryProductDetailsAsync
|
||||||
|
}
|
||||||
|
products =
|
||||||
|
productDetails.sortedBy { it.oneTimePurchaseOfferDetails?.priceAmountMicros }
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onDispose {
|
||||||
|
billingClient?.endConnection()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skuDetailsList.sortedBy { it.priceAmountMicros }
|
products.forEach { product ->
|
||||||
.map { skuDetails ->
|
Button(
|
||||||
val supportButton = MaterialButton(activity)
|
modifier = Modifier.fillMaxWidth(),
|
||||||
supportButton.text = activity.getString(
|
onClick = {
|
||||||
R.string.support_button_purchase,
|
val productDetails = ProductDetailsParams.newBuilder()
|
||||||
skuDetails.title,
|
.setProductDetails(product)
|
||||||
skuDetails.price
|
.build()
|
||||||
)
|
|
||||||
supportButton.setOnClickListener {
|
|
||||||
val flowParams = BillingFlowParams.newBuilder()
|
val flowParams = BillingFlowParams.newBuilder()
|
||||||
.setSkuDetails(skuDetails)
|
.setProductDetailsParamsList(listOf(productDetails))
|
||||||
.build()
|
.build()
|
||||||
billingClient.launchBillingFlow(activity, flowParams)
|
billingClient?.launchBillingFlow(context as Activity, flowParams)
|
||||||
}
|
|
||||||
supportButton
|
|
||||||
}
|
|
||||||
.let {
|
|
||||||
supportLinks.postValue(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBillingServiceDisconnected() {
|
|
||||||
billingClient.startConnection(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPurchasesUpdated(result: BillingResult, purchases: MutableList<Purchase>?) {
|
|
||||||
purchases?.forEach { purchase ->
|
|
||||||
val consumeParams = ConsumeParams.newBuilder()
|
|
||||||
.setPurchaseToken(purchase.purchaseToken)
|
|
||||||
.build()
|
|
||||||
billingClient.consumeAsync(consumeParams) { _, _ ->
|
|
||||||
Toast.makeText(
|
|
||||||
activity,
|
|
||||||
activity.getString(R.string.support_thank_you),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
context.getString(
|
||||||
|
R.string.support_button_purchase,
|
||||||
|
product.name,
|
||||||
|
product.oneTimePurchaseOfferDetails?.formattedPrice
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue