Compare commits
2 commits
72d4a797ea
...
27cd0a829e
Author | SHA1 | Date | |
---|---|---|---|
|
27cd0a829e | ||
|
2939fb55d1 |
16 changed files with 318 additions and 180 deletions
|
@ -29,7 +29,7 @@ android {
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled = false
|
minifyEnabled = false
|
||||||
signingConfig signingConfigs.release
|
signingConfig = signingConfigs.release
|
||||||
proguardFiles(getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro')
|
proguardFiles(getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,13 @@ class MainActivity : AppCompatActivity() {
|
||||||
.commit()
|
.commit()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.action_services -> {
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.replace(R.id.fragmentContainer, ServiceSettingsFragment())
|
||||||
|
.addToBackStack(null)
|
||||||
|
.commit()
|
||||||
|
true
|
||||||
|
}
|
||||||
R.id.action_contacts -> {
|
R.id.action_contacts -> {
|
||||||
supportFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
.replace(R.id.fragmentContainer, ContactsFragment())
|
.replace(R.id.fragmentContainer, ContactsFragment())
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package partisan.weforge.xyz.pulse
|
package partisan.weforge.xyz.pulse
|
||||||
|
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -8,6 +10,7 @@ import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
import partisan.weforge.xyz.pulse.databinding.FragmentPopupSettingsBinding
|
import partisan.weforge.xyz.pulse.databinding.FragmentPopupSettingsBinding
|
||||||
|
|
||||||
class PopupSettingsFragment : Fragment() {
|
class PopupSettingsFragment : Fragment() {
|
||||||
|
@ -30,85 +33,61 @@ class PopupSettingsFragment : Fragment() {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
prefs = Preferences(requireContext())
|
val services = listOf(
|
||||||
window = PopupWindow(requireContext(), null)
|
ServiceEntry(
|
||||||
|
"vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call",
|
||||||
|
R.string.destination_signal,
|
||||||
|
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call")
|
||||||
|
),
|
||||||
|
ServiceEntry(
|
||||||
|
"vnd.android.cursor.item/vnd.org.telegram.messenger.android.call",
|
||||||
|
R.string.destination_telegram,
|
||||||
|
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.org.telegram.messenger.android.call")
|
||||||
|
),
|
||||||
|
ServiceEntry(
|
||||||
|
"vnd.android.cursor.item/vnd.ch.threema.app.call",
|
||||||
|
R.string.destination_threema,
|
||||||
|
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.ch.threema.app.call")
|
||||||
|
),
|
||||||
|
ServiceEntry(
|
||||||
|
"vnd.android.cursor.item/vnd.com.whatsapp.voip.call",
|
||||||
|
R.string.destination_whatsapp,
|
||||||
|
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.com.whatsapp.voip.call")
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
val screenHeight = getScreenHeightPx()
|
val adapter = ServiceAdapter(
|
||||||
|
context = requireContext(),
|
||||||
binding.apply {
|
services = services.toMutableList(),
|
||||||
redirectionDelay.value = (prefs.redirectionDelay / 1000).toFloat()
|
onReordered = { updatedList ->
|
||||||
redirectionDelay.setLabelFormatter {
|
updatedList.forEachIndexed { index, entry ->
|
||||||
String.format("%.1f", it)
|
requireContext().setServicePriority(entry.mimetype, index)
|
||||||
}
|
|
||||||
redirectionDelay.addOnChangeListener { _, value, _ ->
|
|
||||||
prefs.redirectionDelay = (value * 1000).toLong()
|
|
||||||
}
|
|
||||||
|
|
||||||
popupEnabledCheckbox.isChecked = prefs.popupEnabled
|
|
||||||
popupEnabledCheckbox.setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
prefs.popupEnabled = isChecked
|
|
||||||
}
|
|
||||||
|
|
||||||
popupPreview.setOnClickListener {
|
|
||||||
window.preview()
|
|
||||||
}
|
|
||||||
|
|
||||||
popupHeightSlider.valueFrom = 0f
|
|
||||||
popupHeightSlider.valueTo = screenHeight.toFloat()
|
|
||||||
popupHeightSlider.value = prefs.popupPosition.toFloat()
|
|
||||||
popupHeightSlider.addOnChangeListener { _, value, _ ->
|
|
||||||
prefs.popupPosition = value.toInt().coerceIn(0, screenHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
val services = listOf(
|
|
||||||
ServiceEntry(
|
|
||||||
"vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call",
|
|
||||||
R.string.destination_signal,
|
|
||||||
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call")
|
|
||||||
),
|
|
||||||
ServiceEntry(
|
|
||||||
"vnd.android.cursor.item/vnd.org.telegram.messenger.android.call",
|
|
||||||
R.string.destination_telegram,
|
|
||||||
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.org.telegram.messenger.android.call")
|
|
||||||
),
|
|
||||||
ServiceEntry(
|
|
||||||
"vnd.android.cursor.item/vnd.ch.threema.app.call",
|
|
||||||
R.string.destination_threema,
|
|
||||||
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.ch.threema.app.call")
|
|
||||||
),
|
|
||||||
ServiceEntry(
|
|
||||||
"vnd.android.cursor.item/vnd.com.whatsapp.voip.call",
|
|
||||||
R.string.destination_whatsapp,
|
|
||||||
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.com.whatsapp.voip.call")
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
val adapter = ServiceAdapter(
|
|
||||||
context = requireContext(),
|
|
||||||
services = services.toMutableList(),
|
|
||||||
onReordered = { updatedList ->
|
|
||||||
updatedList.forEachIndexed { index, entry ->
|
|
||||||
requireContext().setServicePriority(entry.mimetype, index)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
serviceRecycler.adapter = adapter
|
|
||||||
serviceRecycler.layoutManager = LinearLayoutManager(requireContext())
|
|
||||||
|
|
||||||
val touchHelper = ItemTouchHelper(adapter.dragHelper)
|
|
||||||
touchHelper.attachToRecyclerView(serviceRecycler)
|
|
||||||
|
|
||||||
adapter.setDragStartListener { viewHolder ->
|
|
||||||
touchHelper.startDrag(viewHolder)
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.serviceRecycler.adapter = adapter
|
||||||
|
binding.serviceRecycler.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
|
||||||
|
val touchHelper = ItemTouchHelper(adapter.dragHelper)
|
||||||
|
touchHelper.attachToRecyclerView(binding.serviceRecycler)
|
||||||
|
|
||||||
|
adapter.setDragStartListener { viewHolder ->
|
||||||
|
touchHelper.startDrag(viewHolder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getScreenHeightPx(): Int {
|
private fun getScreenHeightPx(): Int {
|
||||||
val metrics = DisplayMetrics()
|
val wm = requireContext().getSystemService<android.view.WindowManager>()!!
|
||||||
requireActivity().windowManager.defaultDisplay.getMetrics(metrics)
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
return metrics.heightPixels
|
val bounds: Rect = wm.currentWindowMetrics.bounds
|
||||||
|
bounds.height()
|
||||||
|
} else {
|
||||||
|
val metrics = DisplayMetrics()
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
requireActivity().windowManager.defaultDisplay.getMetrics(metrics)
|
||||||
|
metrics.heightPixels
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
|
|
@ -66,8 +66,8 @@ class ServiceAdapter(
|
||||||
viewHolder: RecyclerView.ViewHolder,
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
target: RecyclerView.ViewHolder
|
target: RecyclerView.ViewHolder
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val from = viewHolder.adapterPosition
|
val from = viewHolder.bindingAdapterPosition
|
||||||
val to = target.adapterPosition
|
val to = target.bindingAdapterPosition
|
||||||
services.add(to, services.removeAt(from))
|
services.add(to, services.removeAt(from))
|
||||||
notifyItemMoved(from, to)
|
notifyItemMoved(from, to)
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
package partisan.weforge.xyz.pulse
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import partisan.weforge.xyz.pulse.databinding.FragmentServiceSettingsBinding
|
||||||
|
|
||||||
|
class ServiceSettingsFragment : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: FragmentServiceSettingsBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentServiceSettingsBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val services = listOf(
|
||||||
|
ServiceEntry(
|
||||||
|
"vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call",
|
||||||
|
R.string.destination_signal,
|
||||||
|
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call")
|
||||||
|
),
|
||||||
|
ServiceEntry(
|
||||||
|
"vnd.android.cursor.item/vnd.org.telegram.messenger.android.call",
|
||||||
|
R.string.destination_telegram,
|
||||||
|
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.org.telegram.messenger.android.call")
|
||||||
|
),
|
||||||
|
ServiceEntry(
|
||||||
|
"vnd.android.cursor.item/vnd.ch.threema.app.call",
|
||||||
|
R.string.destination_threema,
|
||||||
|
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.ch.threema.app.call")
|
||||||
|
),
|
||||||
|
ServiceEntry(
|
||||||
|
"vnd.android.cursor.item/vnd.com.whatsapp.voip.call",
|
||||||
|
R.string.destination_whatsapp,
|
||||||
|
requireContext().isServiceEnabled("vnd.android.cursor.item/vnd.com.whatsapp.voip.call")
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
val adapter = ServiceAdapter(
|
||||||
|
context = requireContext(),
|
||||||
|
services = services.toMutableList(),
|
||||||
|
onReordered = { updatedList ->
|
||||||
|
updatedList.forEachIndexed { index, entry ->
|
||||||
|
requireContext().setServicePriority(entry.mimetype, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.serviceRecycler.adapter = adapter
|
||||||
|
binding.serviceRecycler.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
|
||||||
|
val touchHelper = ItemTouchHelper(adapter.dragHelper)
|
||||||
|
touchHelper.attachToRecyclerView(binding.serviceRecycler)
|
||||||
|
|
||||||
|
adapter.setDragStartListener { viewHolder ->
|
||||||
|
touchHelper.startDrag(viewHolder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
}
|
10
app/src/main/res/drawable/heart_24.xml
Normal file
10
app/src/main/res/drawable/heart_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M16.5,3c-1.74,0 -3.41,0.81 -4.5,2.09C10.91,3.81 9.24,3 7.5,3 4.42,3 2,5.42 2,8.5c0,3.78 3.4,6.86 8.55,11.54L12,21.35l1.45,-1.32C18.6,15.36 22,12.28 22,8.5 22,5.42 19.58,3 16.5,3zM12.1,18.55l-0.1,0.1 -0.1,-0.1C7.14,14.24 4,11.39 4,8.5 4,6.5 5.5,5 7.5,5c1.54,0 3.04,0.99 3.57,2.36h1.87C13.46,5.99 14.96,5 16.5,5c2,0 3.5,1.5 3.5,3.5 0,2.89 -3.14,5.74 -7.9,10.05z"/>
|
||||||
|
</vector>
|
13
app/src/main/res/drawable/services_24.xml
Normal file
13
app/src/main/res/drawable/services_24.xml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M14.17,13.71l1.4,-2.42c0.09,-0.15 0.05,-0.34 -0.08,-0.45l-1.48,-1.16c0.03,-0.22 0.05,-0.45 0.05,-0.68s-0.02,-0.46 -0.05,-0.69l1.48,-1.16c0.13,-0.11 0.17,-0.3 0.08,-0.45l-1.4,-2.42c-0.09,-0.15 -0.27,-0.21 -0.43,-0.15L12,4.83c-0.36,-0.28 -0.75,-0.51 -1.18,-0.69l-0.26,-1.85C10.53,2.13 10.38,2 10.21,2h-2.8C7.24,2 7.09,2.13 7.06,2.3L6.8,4.15C6.38,4.33 5.98,4.56 5.62,4.84l-1.74,-0.7c-0.16,-0.06 -0.34,0 -0.43,0.15l-1.4,2.42C1.96,6.86 2,7.05 2.13,7.16l1.48,1.16C3.58,8.54 3.56,8.77 3.56,9s0.02,0.46 0.05,0.69l-1.48,1.16C2,10.96 1.96,11.15 2.05,11.3l1.4,2.42c0.09,0.15 0.27,0.21 0.43,0.15l1.74,-0.7c0.36,0.28 0.75,0.51 1.18,0.69l0.26,1.85C7.09,15.87 7.24,16 7.41,16h2.8c0.17,0 0.32,-0.13 0.35,-0.3l0.26,-1.85c0.42,-0.18 0.82,-0.41 1.18,-0.69l1.74,0.7C13.9,13.92 14.08,13.86 14.17,13.71zM8.81,11c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C10.81,10.1 9.91,11 8.81,11z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M21.92,18.67l-0.96,-0.74c0.02,-0.14 0.04,-0.29 0.04,-0.44c0,-0.15 -0.01,-0.3 -0.04,-0.44l0.95,-0.74c0.08,-0.07 0.11,-0.19 0.05,-0.29l-0.9,-1.55c-0.05,-0.1 -0.17,-0.13 -0.28,-0.1l-1.11,0.45c-0.23,-0.18 -0.48,-0.33 -0.76,-0.44l-0.17,-1.18C18.73,13.08 18.63,13 18.53,13h-1.79c-0.11,0 -0.21,0.08 -0.22,0.19l-0.17,1.18c-0.27,0.12 -0.53,0.26 -0.76,0.44l-1.11,-0.45c-0.1,-0.04 -0.22,0 -0.28,0.1l-0.9,1.55c-0.05,0.1 -0.04,0.22 0.05,0.29l0.95,0.74c-0.02,0.14 -0.03,0.29 -0.03,0.44c0,0.15 0.01,0.3 0.03,0.44l-0.95,0.74c-0.08,0.07 -0.11,0.19 -0.05,0.29l0.9,1.55c0.05,0.1 0.17,0.13 0.28,0.1l1.11,-0.45c0.23,0.18 0.48,0.33 0.76,0.44l0.17,1.18c0.02,0.11 0.11,0.19 0.22,0.19h1.79c0.11,0 0.21,-0.08 0.22,-0.19l0.17,-1.18c0.27,-0.12 0.53,-0.26 0.75,-0.44l1.12,0.45c0.1,0.04 0.22,0 0.28,-0.1l0.9,-1.55C22.03,18.86 22,18.74 21.92,18.67zM17.63,18.83c-0.74,0 -1.35,-0.6 -1.35,-1.35s0.6,-1.35 1.35,-1.35s1.35,0.6 1.35,1.35S18.37,18.83 17.63,18.83z"/>
|
||||||
|
</vector>
|
10
app/src/main/res/drawable/settings_24.xml
Normal file
10
app/src/main/res/drawable/settings_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
|
||||||
|
</vector>
|
|
@ -20,88 +20,70 @@
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:id="@+id/popupEnabledCheckbox"
|
android:id="@+id/popupEnabledCheckbox"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/popup_enabled"
|
android:text="@string/popup_enabled"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/description"
|
app:layout_constraintTop_toBottomOf="@id/description"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@id/popupPreview" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/popupPreview"
|
android:id="@+id/popupPreview"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/test"
|
android:text="@string/test"
|
||||||
app:layout_constraintTop_toTopOf="@id/popupEnabledCheckbox"
|
android:layout_marginTop="8dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/popupEnabledCheckbox"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:layout_marginStart="8dp" />
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:id="@+id/scrollView"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/popupEnabledCheckbox"
|
app:layout_constraintTop_toBottomOf="@id/popupEnabledCheckbox"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
<com.google.android.material.slider.Slider
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/redirectionDelay"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:orientation="vertical">
|
android:layout_height="wrap_content"
|
||||||
|
android:stepSize="0.5"
|
||||||
|
android:valueFrom="2"
|
||||||
|
android:valueTo="4"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:contentDescription="@string/redirection_delay_description" />
|
||||||
|
|
||||||
<com.google.android.material.slider.Slider
|
<TextView
|
||||||
android:id="@+id/redirectionDelay"
|
android:id="@+id/delayDescription"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:stepSize="0.5"
|
android:text="@string/redirection_delay_description"
|
||||||
android:valueFrom="2"
|
android:textSize="12sp"
|
||||||
android:valueTo="4"
|
android:layout_marginTop="4dp" />
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:contentDescription="@string/redirection_delay_description" />
|
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.slider.Slider
|
||||||
android:id="@+id/delayDescription"
|
android:id="@+id/popupHeightSlider"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/redirection_delay_description"
|
android:valueFrom="0"
|
||||||
android:textSize="12sp"
|
android:valueTo="100"
|
||||||
android:layout_marginTop="4dp" />
|
android:stepSize="1"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="@string/popup_position" />
|
||||||
|
|
||||||
<com.google.android.material.slider.Slider
|
<TextView
|
||||||
android:id="@+id/popupHeightSlider"
|
android:id="@+id/heightDescription"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:valueFrom="0"
|
android:text="@string/popup_position"
|
||||||
android:valueTo="100"
|
android:textSize="12sp"
|
||||||
android:stepSize="1"
|
android:layout_marginTop="4dp" />
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:contentDescription="@string/popup_position" />
|
|
||||||
|
|
||||||
<TextView
|
<View
|
||||||
android:id="@+id/heightDescription"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="1dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_marginVertical="16dp"
|
||||||
android:text="@string/popup_position"
|
android:background="?android:attr/listDivider" />
|
||||||
android:textSize="12sp"
|
|
||||||
android:layout_marginTop="4dp" />
|
|
||||||
|
|
||||||
<View
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/serviceRecycler"
|
||||||
android:layout_height="1dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_marginVertical="16dp"
|
android:layout_height="wrap_content"
|
||||||
android:background="?android:attr/listDivider" />
|
android:scrollbars="vertical"
|
||||||
|
android:layout_marginTop="8dp" />
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/serviceRecycler"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:scrollbars="vertical"
|
|
||||||
android:layout_marginTop="8dp" />
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
30
app/src/main/res/layout/fragment_service_settings.xml
Normal file
30
app/src/main/res/layout/fragment_service_settings.xml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?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"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/serviceHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/service_settings_title"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/serviceRecycler"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:scrollbars="vertical"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/serviceHeader"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -6,16 +6,21 @@
|
||||||
android:id="@+id/section_settings"
|
android:id="@+id/section_settings"
|
||||||
android:title="Settings"
|
android:title="Settings"
|
||||||
android:enabled="false" />
|
android:enabled="false" />
|
||||||
<item
|
|
||||||
android:id="@+id/action_popup_settings"
|
|
||||||
android:title="Popup Settings"
|
|
||||||
android:icon="@drawable/tooltip_24px"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_contacts"
|
android:id="@+id/action_contacts"
|
||||||
android:title="Contacts"
|
android:title="Contacts"
|
||||||
android:icon="@drawable/group_24px"
|
android:icon="@drawable/group_24px"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_popup_settings"
|
||||||
|
android:title="Popup"
|
||||||
|
android:icon="@drawable/tooltip_24px"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_services"
|
||||||
|
android:title="Services"
|
||||||
|
android:icon="@drawable/services_24"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
<!-- About section -->
|
<!-- About section -->
|
||||||
<item
|
<item
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<string name="popup_position">Popup position</string>
|
<string name="popup_position">Popup position</string>
|
||||||
<string name="fallback">Fallback</string>
|
<string name="fallback">Fallback</string>
|
||||||
<string name="activate_description">To start, grant the required permissions by tapping the Activate button.</string>
|
<string name="activate_description">To start, grant the required permissions by tapping the Activate button.</string>
|
||||||
|
<string name="service_settings_title">Service Preferences</string>
|
||||||
<string name="activate">Activate</string>
|
<string name="activate">Activate</string>
|
||||||
<string name="navigation_drawer_open">Open menu</string>
|
<string name="navigation_drawer_open">Open menu</string>
|
||||||
<string name="navigation_drawer_close">Close menu</string>
|
<string name="navigation_drawer_close">Close menu</string>
|
||||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
6
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,7 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-milestone-8-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
|
47
gradlew
vendored
47
gradlew
vendored
|
@ -15,6 +15,8 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
|
@ -55,7 +57,7 @@
|
||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
@ -80,13 +82,11 @@ do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
@ -114,7 +114,7 @@ case "$( uname )" in #(
|
||||||
NONSTOP* ) nonstop=true ;;
|
NONSTOP* ) nonstop=true ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH="\\\"\\\""
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
|
@ -133,22 +133,29 @@ location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
|
@ -193,18 +200,28 @@ if "$cygwin" || "$msys" ; then
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
# double quotes to make sure that they get re-expanded; and
|
|
||||||
# * put everything else in single quotes, so that it's not re-expanded.
|
# Collect all arguments for the java command:
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
|
# and any embedded shellness will be escaped.
|
||||||
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
-classpath "$CLASSPATH" \
|
-classpath "$CLASSPATH" \
|
||||||
org.gradle.wrapper.GradleWrapperMain \
|
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
# Use "xargs" to parse quoted args.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
|
41
gradlew.bat
vendored
41
gradlew.bat
vendored
|
@ -13,8 +13,10 @@
|
||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
|
@ -25,7 +27,8 @@
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
@ -56,32 +59,34 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
set CLASSPATH=
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute Gradle
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
exit /b 1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue