Skip to content

Commit

Permalink
add composables OpenDialerApp CallsScreen, CallDetailScreen, Contacts…
Browse files Browse the repository at this point in the history
…Screen
  • Loading branch information
oxcened committed Oct 4, 2024
1 parent 2622f2f commit 9c98711
Show file tree
Hide file tree
Showing 22 changed files with 992 additions and 85 deletions.
15 changes: 15 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ android {
}
buildFeatures {
viewBinding true
compose true
}
namespace 'dev.alenajam.opendialer'
lint {
Expand All @@ -58,6 +59,9 @@ android {
compileOptions {
coreLibraryDesugaringEnabled true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.2"
}
}

dependencies {
Expand Down Expand Up @@ -105,6 +109,17 @@ dependencies {

testImplementation 'junit:junit:4.13.2'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'

def composeBom = platform('androidx.compose:compose-bom:2023.10.01')
implementation composeBom
androidTestImplementation composeBom
implementation 'androidx.compose.material3:material3'
implementation 'androidx.compose.ui:ui-tooling-preview'
debugImplementation 'androidx.compose.ui:ui-tooling'
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
implementation 'androidx.compose.material:material-icons-extended'
implementation "androidx.compose.ui:ui-viewbinding"
}

repositories {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.viewpager2.adapter.FragmentStateAdapter
Expand All @@ -22,6 +24,7 @@ import dev.alenajam.opendialer.feature.contacts.ContactsFragment
import dev.alenajam.opendialer.feature.contactsSearch.SearchContactsFragment
import dev.alenajam.opendialer.feature.settings.ProfileFragment
import dev.alenajam.opendialer.features.main.MainFragmentDirections.Companion.actionHomeFragmentToSearchContactsFragment
import dev.alenajam.opendialer.ui.OpenDialerApp

class MainFragment :
Fragment(),
Expand Down Expand Up @@ -53,8 +56,21 @@ class MainFragment :
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
/*_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root*/

return ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
OpenDialerApp(
openDialpad = {
val action =
actionHomeFragmentToSearchContactsFragment(SearchContactsFragment.InitiationType.DIALPAD)
findNavController().safeNavigate(action)
}
)
}
}
}

override fun onDestroyView() {
Expand All @@ -65,7 +81,7 @@ class MainFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

onStatusBarColorChange?.onColorChange(view.context.getColor(R.color.windowBackground))
/*onStatusBarColorChange?.onColorChange(view.context.getColor(R.color.windowBackground))
binding.bottomNavigation.setOnNavigationItemSelectedListener(this)
binding.bottomNavigation.itemIconTintList = null
Expand All @@ -77,7 +93,7 @@ class MainFragment :
adapter = viewPagerAdapter
isUserInputEnabled = false
registerOnPageChangeCallback(OnPageChange())
}
}*/
}

private fun setPage(fragment: Tab) {
Expand Down
96 changes: 96 additions & 0 deletions app/src/main/java/dev/alenajam/opendialer/ui/OpenDialerApp.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package dev.alenajam.opendialer.ui

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccessTimeFilled
import androidx.compose.material.icons.filled.People
import androidx.compose.material.icons.outlined.AccessTime
import androidx.compose.material.icons.outlined.Dialpad
import androidx.compose.material.icons.outlined.People
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SearchBar
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
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.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidViewBinding
import dev.alenajam.opendialer.R
import dev.alenajam.opendialer.databinding.AppFragmentCallsBinding
import dev.alenajam.opendialer.databinding.AppFragmentContactsBinding

@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun OpenDialerApp(
openDialpad: () -> Unit
) {
var selectedNavigationItem by remember { mutableStateOf("CALLS") }
Scaffold(
topBar = {
SearchBar(
query = "",
active = false,
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, bottom = 8.dp),
placeholder = { Text(text = stringResource(id = R.string.searchContacts)) },
leadingIcon = { Icon(imageVector = Icons.Outlined.Search, contentDescription = null) },
onSearch = {},
onActiveChange = {},
onQueryChange = {},
) {}
},
bottomBar = {
NavigationBar {
val isSelected = { item: String -> item == selectedNavigationItem }
NavigationBarItem(
selected = isSelected("CALLS"),
icon = {
Icon(
imageVector = if (isSelected("CALLS")) Icons.Filled.AccessTimeFilled else Icons.Outlined.AccessTime,
contentDescription = null
)
},
label = { Text("Recents") },
onClick = { selectedNavigationItem = "CALLS" },
)

NavigationBarItem(
selected = isSelected("CONTACTS"),
icon = {
Icon(
imageVector = if (isSelected("CONTACTS")) Icons.Filled.People else Icons.Outlined.People,
contentDescription = null
)
},
label = { Text("Contacts") },
onClick = { selectedNavigationItem = "CONTACTS" },
)
}
},
floatingActionButton = {
FloatingActionButton(onClick = openDialpad) {
Icon(imageVector = Icons.Outlined.Dialpad, contentDescription = null)
}
}
) { innerPadding ->
Surface(modifier = Modifier.padding(innerPadding)) {
when (selectedNavigationItem) {
"CALLS" -> AndroidViewBinding(AppFragmentCallsBinding::inflate)
"CONTACTS" -> AndroidViewBinding(AppFragmentContactsBinding::inflate)
}
}
}
}
6 changes: 6 additions & 0 deletions app/src/main/res/layout/app_fragment_calls.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container_view_calls"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="dev.alenajam.opendialer.feature.calls.RecentsFragment" />
6 changes: 6 additions & 0 deletions app/src/main/res/layout/app_fragment_contacts.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container_view_contacts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="dev.alenajam.opendialer.feature.contacts.ContactsFragment" />
13 changes: 12 additions & 1 deletion core/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ android {
}

dependencies {

implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.10.0")
Expand All @@ -40,6 +39,18 @@ dependencies {
implementation("androidx.navigation:navigation-ui-ktx:2.7.5")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("com.google.code.gson:gson:2.9.0")

val composeBom = platform("androidx.compose:compose-bom:2023.10.01")
implementation(composeBom)
androidTestImplementation(composeBom)
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui-tooling-preview")
debugImplementation("androidx.compose.ui:ui-tooling")
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-test-manifest")
implementation("androidx.compose.material:material-icons-extended")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
implementation("androidx.compose.runtime:runtime-livedata")
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public static void startInCallUI(Context context) throws ClassNotFoundException
public static void makeCall(Context context, String number) {
if (PermissionUtils.hasMakeCallPermission(context)) {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.fromParts("tel", number, null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

TelecomManager telecomManager = (TelecomManager) context.getSystemService(TELECOM_SERVICE);
if (telecomManager == null) return;
Expand Down Expand Up @@ -153,7 +154,9 @@ public static void makeCall(Context context, String number) {
}

public static void makeSms(Context context, String number) {
context.startActivity(new Intent(Intent.ACTION_SENDTO, Uri.fromParts("smsto", number, null)));
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("smsto", number, null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}

public static void copyToClipobard(Context context, String text) {
Expand All @@ -169,6 +172,7 @@ public static void showContactDetail(Context context, int contactId) {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(contactId));
intent.setData(uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}

Expand Down Expand Up @@ -197,6 +201,7 @@ public static void addContactAsExisting(Context context, String number) {
Intent addExistingIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
addExistingIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
addExistingIntent.putExtra(ContactsContract.Intents.Insert.PHONE, number);
addExistingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(addExistingIntent);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package dev.alenajam.opendialer.core.common

import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.painter.Painter

/**
* Create and return a new [Painter] that wraps [painter] with its [alpha], [colorFilter], or [onDraw] overwritten.
*/
fun forwardingPainter(
painter: Painter,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null,
onDraw: DrawScope.(ForwardingDrawInfo) -> Unit = DefaultOnDraw,
): Painter = ForwardingPainter(painter, alpha, colorFilter, onDraw)

data class ForwardingDrawInfo(
val painter: Painter,
val alpha: Float,
val colorFilter: ColorFilter?,
)

private class ForwardingPainter(
private val painter: Painter,
private var alpha: Float,
private var colorFilter: ColorFilter?,
private val onDraw: DrawScope.(ForwardingDrawInfo) -> Unit,
) : Painter() {

private var info = newInfo()

override val intrinsicSize get() = painter.intrinsicSize

override fun applyAlpha(alpha: Float): Boolean {
if (alpha != DefaultAlpha) {
this.alpha = alpha
this.info = newInfo()
}
return true
}

override fun applyColorFilter(colorFilter: ColorFilter?): Boolean {
if (colorFilter != null) {
this.colorFilter = colorFilter
this.info = newInfo()
}
return true
}

override fun DrawScope.onDraw() = onDraw(info)

private fun newInfo() = ForwardingDrawInfo(painter, alpha, colorFilter)
}

private val DefaultOnDraw: DrawScope.(ForwardingDrawInfo) -> Unit = { info ->
with(info.painter) {
draw(size, info.alpha, info.colorFilter)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import java.io.Serializable
import java.util.Date

@Keep
class DialerCall(
data class DialerCall(
val id: Int,
val number: String?,
val date: Date,
Expand Down Expand Up @@ -107,6 +107,7 @@ class DialerCall(
}

fun isAnonymous(): Boolean = contactInfo.number.isNullOrBlank()
fun isContactSaved(): Boolean = !contactInfo.name.isNullOrBlank()
}

fun equalNumbers(number1: String?, number2: String?): Boolean {
Expand Down
18 changes: 18 additions & 0 deletions feature/callDetail/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ android {
}
buildFeatures {
viewBinding = true
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.2"
}
}

Expand Down Expand Up @@ -65,6 +69,20 @@ dependencies {

implementation("com.squareup.picasso:picasso:2.71828")
implementation("org.ocpsoft.prettytime:prettytime:4.0.1.Final")

val composeBom = platform("androidx.compose:compose-bom:2023.10.01")
implementation(composeBom)
androidTestImplementation(composeBom)
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui-tooling-preview")
debugImplementation("androidx.compose.ui:ui-tooling")
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-test-manifest")
implementation("androidx.compose.material:material-icons-extended")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
implementation("androidx.compose.runtime:runtime-livedata")

implementation("io.coil-kt:coil-compose:2.5.0")
}

kotlin {
Expand Down
Loading

0 comments on commit 9c98711

Please sign in to comment.