Some final changes
|
@ -1,9 +1,6 @@
|
|||
name: Android Release Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
workflow_dispatch: {}
|
||||
|
||||
jobs:
|
||||
|
|
1
.gitignore
vendored
|
@ -15,3 +15,4 @@
|
|||
local.properties
|
||||
release-key.jks
|
||||
check.py
|
||||
round.sh
|
12
README.md
|
@ -30,11 +30,19 @@ Redirecting outgoing calls to E2EE apps.
|
|||
|
||||
<p align="center">
|
||||
<span>
|
||||
<img src="https://weforge.xyz/partisan/Pulse/raw/branch/main/data/screenshot.png" alt="Main screen" height="500" style="border-radius: 8px;">
|
||||
<img src="https://weforge.xyz/partisan/Pulse/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png" alt="Main screen" height="500" style="border-radius: 8px;">
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<img src="https://weforge.xyz/partisan/Pulse/raw/branch/main/data/screenshot-redirecting.png" alt="Redirecting popup" height="500" style="border-radius: 8px;">
|
||||
<img src="https://weforge.xyz/partisan/Pulse/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png" alt="Redirecting popup" height="500" style="border-radius: 8px;">
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<img src="https://weforge.xyz/partisan/Pulse/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png" alt="Redirecting popup" height="500" style="border-radius: 8px;">
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<img src="https://weforge.xyz/partisan/Pulse/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png" alt="Redirecting popup" height="500" style="border-radius: 8px;">
|
||||
</span>
|
||||
</p>
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ class MainActivity : AppCompatActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
prefs = Preferences(this)
|
||||
updateDonationIcon()
|
||||
setContentView(binding.root)
|
||||
prefs = Preferences(this)
|
||||
setSupportActionBar(binding.topAppBar)
|
||||
|
@ -50,6 +52,13 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
binding.navigationView.setNavigationItemSelectedListener { item ->
|
||||
when (item.itemId) {
|
||||
R.id.action_home -> {
|
||||
supportFragmentManager.popBackStack(null, androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragmentContainer, MainFragment())
|
||||
.commit()
|
||||
true
|
||||
}
|
||||
R.id.action_popup_settings -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragmentContainer, PopupSettingsFragment())
|
||||
|
@ -122,6 +131,16 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateDonationIcon() {
|
||||
val donateItem = binding.navigationView.menu.findItem(R.id.action_donate)
|
||||
donateItem.setIcon(
|
||||
if (prefs.isDonationActivated)
|
||||
R.drawable.heart_filled_24
|
||||
else
|
||||
R.drawable.heart_24
|
||||
)
|
||||
}
|
||||
|
||||
fun setAppBarTitle(vararg parts: String) {
|
||||
binding.topAppBar.title = parts.joinToString(" > ")
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.widget.ArrayAdapter
|
|||
import android.widget.AdapterView
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.Spinner
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.core.content.getSystemService
|
||||
import partisan.weforge.xyz.pulse.databinding.FragmentPopupSettingsBinding
|
||||
|
@ -34,6 +35,7 @@ class PopupSettingsFragment : Fragment() {
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
updateSpinner()
|
||||
(requireActivity() as? MainActivity)?.apply {
|
||||
setAppBarTitle(getString(R.string.settings_name), getString(R.string.popup_name))
|
||||
setupPopupToggle(true, prefs.popupEnabled) { isChecked ->
|
||||
|
@ -71,21 +73,7 @@ class PopupSettingsFragment : Fragment() {
|
|||
prefs.redirectionDelay = (value * 1000).toLong()
|
||||
}
|
||||
|
||||
val effectNames = resources.getStringArray(R.array.popup_effects)
|
||||
val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, effectNames)
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
binding.popupEffectSpinner.adapter = adapter
|
||||
|
||||
// Select current setting
|
||||
binding.popupEffectSpinner.setSelection(prefs.popupEffect.ordinal)
|
||||
|
||||
binding.popupEffectSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
|
||||
prefs.popupEffect = Preferences.PopupEffect.values()[position]
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>) {}
|
||||
}
|
||||
updateSpinner()
|
||||
|
||||
val screenHeight = getScreenHeightPx()
|
||||
binding.popupHeightSlider.valueFrom = 0f
|
||||
|
@ -119,6 +107,44 @@ class PopupSettingsFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateSpinner() {
|
||||
val allEffects = Preferences.PopupEffect.values()
|
||||
val effectLabels = resources.getStringArray(R.array.popup_effects)
|
||||
|
||||
val availableEffects = prefs.getAvailablePopupEffects() + listOf(
|
||||
Preferences.PopupEffect.NONE,
|
||||
Preferences.PopupEffect.RANDOM
|
||||
)
|
||||
|
||||
val displayNames = allEffects.mapIndexed { index, effect ->
|
||||
val baseName = effectLabels.getOrElse(index) { effect.name }
|
||||
if (!prefs.isDonationActivated && effect !in availableEffects)
|
||||
"$baseName 🔒"
|
||||
else
|
||||
baseName
|
||||
}
|
||||
|
||||
val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, displayNames)
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
binding.popupEffectSpinner.adapter = adapter
|
||||
|
||||
binding.popupEffectSpinner.setSelection(prefs.popupEffect.ordinal)
|
||||
|
||||
binding.popupEffectSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
|
||||
val selectedEffect = allEffects[position]
|
||||
if (!prefs.isDonationActivated && selectedEffect !in prefs.getAvailablePopupEffects()) {
|
||||
Toast.makeText(requireContext(), getString(R.string.donate_lock), Toast.LENGTH_SHORT).show()
|
||||
binding.popupEffectSpinner.setSelection(prefs.popupEffect.ordinal)
|
||||
} else {
|
||||
prefs.popupEffect = selectedEffect
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>) {}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
|
|
|
@ -174,7 +174,7 @@ class PopupWindow(
|
|||
}
|
||||
|
||||
val effect = when (prefs.popupEffect) {
|
||||
PopupEffect.RANDOM -> PopupEffect.values().filter { it != PopupEffect.RANDOM && it != PopupEffect.NONE }.random()
|
||||
PopupEffect.RANDOM -> prefs.getAvailablePopupEffects().random()
|
||||
else -> prefs.popupEffect
|
||||
}
|
||||
currentEffect = effect
|
||||
|
|
|
@ -31,7 +31,7 @@ class Preferences(private val context: Context) {
|
|||
|
||||
// Whether user enabled/disabled the service manually by tiggle button
|
||||
var isServiceEnabledByUser: Boolean
|
||||
get() = prefs.getBoolean(SERVICE_ENABLED, false)
|
||||
get() = prefs.getBoolean(SERVICE_ENABLED, true)
|
||||
set(value) = prefs.edit { putBoolean(SERVICE_ENABLED, value) }
|
||||
|
||||
// True only if all required permissions + toggle are satisfied
|
||||
|
@ -110,6 +110,18 @@ class Preferences(private val context: Context) {
|
|||
private fun makeKeyEnabled(mimetype: String) = "enabled_$mimetype"
|
||||
private fun makeKeyPriority(mimetype: String) = "priority_$mimetype"
|
||||
|
||||
fun getAvailablePopupEffects(): List<PopupEffect> {
|
||||
val locked = listOf(
|
||||
PopupEffect.FLOP,
|
||||
PopupEffect.MATRIX,
|
||||
PopupEffect.SLIDE_SNAP,
|
||||
PopupEffect.GAMER_MODE
|
||||
)
|
||||
return PopupEffect.values().filter {
|
||||
isDonationActivated || it !in locked
|
||||
}.filter { it != PopupEffect.RANDOM && it != PopupEffect.NONE }
|
||||
}
|
||||
|
||||
fun isServiceEnabled(mimetype: String): Boolean {
|
||||
return prefs.getBoolean(makeKeyEnabled(mimetype), true)
|
||||
}
|
||||
|
|
|
@ -85,20 +85,20 @@ class WelcomeActivity : AppCompatActivity() {
|
|||
binding.konfettiView.visibility = View.VISIBLE
|
||||
binding.konfettiView.start(
|
||||
Party(
|
||||
speed = 30f,
|
||||
speed = 25f,
|
||||
maxSpeed = 50f,
|
||||
damping = 0.9f,
|
||||
spread = 360,
|
||||
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
|
||||
position = Position.Relative(relativeX, relativeY),
|
||||
emitter = Emitter(duration = 2, TimeUnit.SECONDS).perSecond(100)
|
||||
emitter = Emitter(duration = 1, TimeUnit.SECONDS).perSecond(80)
|
||||
)
|
||||
)
|
||||
|
||||
binding.konfettiView.postDelayed({
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
}, 2000)
|
||||
}, 1500)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,14 @@
|
|||
android:clickable="true"
|
||||
android:focusable="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reminderText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/donate_toast_reminder"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginBottom="12dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/kofiButton"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -1,45 +1,58 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<!-- Home (main screen toggle) -->
|
||||
<group android:checkableBehavior="none">
|
||||
<item
|
||||
android:id="@+id/action_home"
|
||||
android:title="@string/home_name"
|
||||
android:icon="@drawable/ic_power_settings_new_24"
|
||||
app:showAsAction="never" />
|
||||
</group>
|
||||
|
||||
<!-- Settings section -->
|
||||
<item
|
||||
<!-- <item
|
||||
android:id="@+id/section_settings"
|
||||
android:title="@string/settings_name"
|
||||
android:enabled="false" />
|
||||
<item
|
||||
android:id="@+id/action_contacts"
|
||||
android:title="@string/whitelist_name"
|
||||
android:icon="@drawable/group_24px"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_popup_settings"
|
||||
android:title="@string/popup_name"
|
||||
android:icon="@drawable/tooltip_24px"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_services"
|
||||
android:title="@string/services_name"
|
||||
android:icon="@drawable/services_24"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_redirect_settings"
|
||||
android:title="@string/redirect_name"
|
||||
android:icon="@drawable/call_split_24px"
|
||||
app:showAsAction="never" />
|
||||
android:enabled="false" /> -->
|
||||
<group android:checkableBehavior="none">
|
||||
<item
|
||||
android:id="@+id/action_contacts"
|
||||
android:title="@string/whitelist_name"
|
||||
android:icon="@drawable/group_24px"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_popup_settings"
|
||||
android:title="@string/popup_name"
|
||||
android:icon="@drawable/tooltip_24px"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_services"
|
||||
android:title="@string/services_name"
|
||||
android:icon="@drawable/services_24"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_redirect_settings"
|
||||
android:title="@string/redirect_name"
|
||||
android:icon="@drawable/call_split_24px"
|
||||
app:showAsAction="never" />
|
||||
</group>
|
||||
|
||||
<!-- About section -->
|
||||
<item
|
||||
<!-- <item
|
||||
android:id="@+id/section_about"
|
||||
android:title="@string/about_name"
|
||||
android:enabled="false" />
|
||||
<item
|
||||
android:id="@+id/action_donate"
|
||||
android:title="Donate"
|
||||
android:icon="@drawable/heart_24"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_about"
|
||||
android:title="@string/about_name"
|
||||
android:icon="@drawable/info_24px"
|
||||
app:showAsAction="never" />
|
||||
android:enabled="false" /> -->
|
||||
<group android:checkableBehavior="none">
|
||||
<item
|
||||
android:id="@+id/action_donate"
|
||||
android:title="Donate"
|
||||
android:icon="@drawable/heart_24"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_about"
|
||||
android:title="@string/about_name"
|
||||
android:icon="@drawable/info_24px"
|
||||
app:showAsAction="never" />
|
||||
</group>
|
||||
</menu>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<string name="app_name">Pulse</string>
|
||||
<string name="description">Redirecting outgoing calls to E2EE apps.</string>
|
||||
<string name="popup">Redirecting to %1$s</string>
|
||||
<string name="home_name">Home</string>
|
||||
<string name="settings_name">Settings</string>
|
||||
<string name="popup_name">Popup</string>
|
||||
<string name="services_name">Services</string>
|
||||
|
@ -55,6 +56,7 @@
|
|||
<string name="donate_token_instruction">Enter your Ko-fi token:</string>
|
||||
<string name="donate_token_hint">token: abcd1234efgh5678</string>
|
||||
<string name="donate_token_activate">Activate Token</string>
|
||||
<string name="donate_lock">Donate to unlock this effect</string>
|
||||
|
||||
<!-- DonateFragment -->
|
||||
<string name="donate_token_copied">Token copied to clipboard</string>
|
||||
|
|
Before Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 127 KiB |
|
@ -14,3 +14,9 @@ v2.0.0
|
|||
Fixes:
|
||||
- Popup now uses system Material colors
|
||||
- Fixed issue where service priority changes didn't work
|
||||
|
||||
Misc:
|
||||
- Updated Gradle to v8.14.1
|
||||
- Updated screenshots to include new looks of the app.
|
||||
- Updated description.
|
||||
- Added temporary "v2.0" to store icon to indicate new version.
|
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 142 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 163 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 121 KiB |
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-milestone-8-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
2
gradlew
vendored
|
@ -1,7 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
|