Skip to content

Commit

Permalink
saving progress
Browse files Browse the repository at this point in the history
  • Loading branch information
gargVader committed Jun 29, 2024
1 parent 712add2 commit 3f2976f
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 27 deletions.
1 change: 1 addition & 0 deletions core_camera/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ android {
dependencies {
// Project
implementation(project(":core_floating_window"))
implementation(project(":core_notification"))
}

// Allow references to generated code
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,29 @@
package com.screensnap.core.camera

import android.content.Context
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
import android.widget.Space
import android.widget.TextView
import androidx.camera.core.CameraSelector
import androidx.camera.view.LifecycleCameraController
import androidx.camera.view.PreviewView
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Camera
import androidx.compose.material.icons.filled.Cameraswitch
import androidx.compose.material.icons.filled.Cancel
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.outlined.Cameraswitch
import androidx.compose.material.icons.outlined.Cancel
import androidx.compose.material.icons.outlined.UnfoldMore
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocal
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
Expand All @@ -41,10 +32,8 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import kotlin.math.roundToInt

@Composable
fun CameraPreview(
Expand All @@ -62,6 +51,10 @@ fun CameraPreview(
}
}

var offsetX by remember { mutableFloatStateOf(120f) }
var offsetY by remember { mutableFloatStateOf(120f) }
var isDragging by remember { mutableStateOf(false) }

Column(modifier = Modifier.clickable {
Log.d("Girish", "CameraPreview: onClick")
}) {
Expand All @@ -76,11 +69,11 @@ fun CameraPreview(
}
},
modifier = modifier
.width(120.dp)
.height(120.dp)
.width(offsetX.dp)
.height(offsetY.dp)
)

if (shouldDisplayControls) {
if (shouldDisplayControls || isDragging) {
Icon(
imageVector = Icons.Outlined.Cancel,
contentDescription = "Close",
Expand Down Expand Up @@ -110,6 +103,27 @@ fun CameraPreview(
onClick = { /*TODO*/ },
modifier = Modifier
.align(Alignment.BottomEnd)
.pointerInput(Unit) {
detectDragGestures(
onDragStart = {
isDragging = true
},
onDragEnd = {
isDragging = false
}, onDrag = { change, dragAmount ->
change.consume()
val dragAmountX =
pixelsToDp(dragAmount.x, context.resources.displayMetrics)
val dragAmountY =
pixelsToDp(dragAmount.y, context.resources.displayMetrics)
offsetX += dragAmountX
offsetY += dragAmountY
Log.d(
"Girish",
"CameraPreview: offest=$offsetX, $offsetY, drag=$dragAmountX, $dragAmountY"
)
})
}
) {
Icon(
imageVector = Icons.Outlined.UnfoldMore,
Expand All @@ -134,4 +148,8 @@ fun CameraPreviewPreview() {
onCameraTouchListener = View.OnTouchListener { _, _ -> true },
onCloseClick = {}, shouldDisplayControls = true,
)
}

fun pixelsToDp(pixels: Float, displayMetrics: DisplayMetrics): Float {
return pixels / (displayMetrics.densityDpi / 160f)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import androidx.savedstate.SavedStateRegistry
import androidx.savedstate.SavedStateRegistryController
import androidx.savedstate.SavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
import com.screensnap.core.notification.ScreenSnapNotificationConstants
import com.screensnap.core.notification.ScreenSnapNotificationManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
Expand All @@ -48,6 +50,8 @@ class FloatingCameraService : Service(), SavedStateRegistryOwner, ViewModelStore
private val coroutineScope = CoroutineScope(Dispatchers.Default)
private var coroutineJob: Job? = null

private lateinit var notificationManager: ScreenSnapNotificationManager

private fun createOnTouchListener(
view: View,
floatingWindowLayoutParameters: WindowManager.LayoutParams
Expand Down Expand Up @@ -135,7 +139,14 @@ class FloatingCameraService : Service(), SavedStateRegistryOwner, ViewModelStore

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
return super.onStartCommand(intent, flags, startId)
notificationManager = ScreenSnapNotificationManager(
serviceContext = this,
screenRecorderServiceClass = FloatingCameraService::class.java,
)
val notification = notificationManager.createNotification()
startForeground(ScreenSnapNotificationConstants.NOTIFICATION_ID, notification)

return START_STICKY
}

override fun onDestroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ enum class ScreenSnapNotificationAction(val value: String) {
RECORDING_START(value = createActionName("recording_start")),
RECORDING_PAUSE(value = createActionName("recording_pause")),
RECORDING_RESUME(value = createActionName("recording_resume")),
RECORDING_STOP(value = createActionName("recording_stop"));
RECORDING_STOP(value = createActionName("recording_stop")),
LAUNCH_CAMERA(value = createActionName("launch_camera"));

companion object {
fun fromString(value: String) = values().firstOrNull { it.value == value }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import com.screensnap.core.notification.ScreenSnapNotificationConstants.NOTIFICA

class ScreenSnapNotificationManager(
private val serviceContext: Context,
private val serviceClass: Class<*>,
private val screenRecorderServiceClass: Class<*>,
) {

private var notificationManager: NotificationManager =
serviceContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

private val pausePendingIntent: PendingIntent
get() {
val pauseIntent = Intent(serviceContext, serviceClass).apply {
val pauseIntent = Intent(serviceContext, screenRecorderServiceClass).apply {
action = ScreenSnapNotificationAction.RECORDING_PAUSE.value
}
return PendingIntent.getService(
Expand All @@ -30,7 +30,7 @@ class ScreenSnapNotificationManager(

private val resumePendingIntent: PendingIntent
get() {
val resumeIntent = Intent(serviceContext, serviceClass).apply {
val resumeIntent = Intent(serviceContext, screenRecorderServiceClass).apply {
action = ScreenSnapNotificationAction.RECORDING_RESUME.value
}
return PendingIntent.getService(
Expand All @@ -40,14 +40,24 @@ class ScreenSnapNotificationManager(

private val stopPendingIntent: PendingIntent
get() {
val stopIntent = Intent(serviceContext, serviceClass).apply {
val stopIntent = Intent(serviceContext, screenRecorderServiceClass).apply {
action = ScreenSnapNotificationAction.RECORDING_STOP.value
}
return PendingIntent.getService(
serviceContext, 0, stopIntent, PendingIntent.FLAG_IMMUTABLE
)
}

private val startPendingIntent: PendingIntent
get() {
val startIntent = Intent(serviceContext, screenRecorderServiceClass).apply {
action = ScreenSnapNotificationAction.RECORDING_START.value
}
return PendingIntent.getService(
serviceContext, 0, startIntent, PendingIntent.FLAG_IMMUTABLE
)
}

fun createNotification(isPaused: Boolean = false): Notification {
val view = RemoteViews("com.screensnap.app", R.layout.notification)

Expand Down Expand Up @@ -77,7 +87,8 @@ class ScreenSnapNotificationManager(
onStartRecording: () -> Unit,
onPauseRecording: () -> Unit,
onResumeRecording: () -> Unit,
onStopRecording: () -> Unit
onStopRecording: () -> Unit,
onLaunchCamera: () -> Unit,
): Int {
val action: ScreenSnapNotificationAction =
ScreenSnapNotificationAction.fromString(intent.action ?: "") ?: return START_NOT_STICKY
Expand All @@ -103,6 +114,11 @@ class ScreenSnapNotificationManager(
onStopRecording()
START_NOT_STICKY
}

ScreenSnapNotificationAction.LAUNCH_CAMERA -> {
onLaunchCamera()
START_NOT_STICKY
}
}

}
Expand Down
23 changes: 22 additions & 1 deletion core_notification/src/main/res/layout/notification.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@
android:layout_height="match_parent"
android:orientation="horizontal">


<TextView
android:id="@+id/start_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableTop="@drawable/record"
android:drawableTint="@color/primary"
android:gravity="center"
android:text="@string/start" />

<TextView
android:id="@+id/close_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableTop="@drawable/baseline_cancel_24"
android:drawableTint="@color/primary"
android:gravity="center"
android:text="@string/close" />

<TextView
android:id="@+id/pause_view"
android:layout_width="wrap_content"
Expand All @@ -23,7 +44,7 @@
android:drawableTint="@color/primary"
android:gravity="center"
android:text="@string/resume"
android:visibility="gone" />
/>


<TextView
Expand Down
1 change: 1 addition & 0 deletions core_screen_recorder/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies {
implementation(project(":core_datastore"))
implementation(project(":core_notification"))
implementation(project(":core_ui"))
implementation(project(":core_camera"))
}

// Allow references to generated code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Intent
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.os.IBinder
import com.screensnap.core.camera.FloatingCameraService
import com.screensnap.core.datastore.ScreenSnapDatastore
import com.screensnap.core.notification.ScreenSnapNotificationConstants
import com.screensnap.core.notification.ScreenSnapNotificationManager
Expand Down Expand Up @@ -49,14 +50,15 @@ class ScreenRecorderService : Service() {
): Int {
notificationManager = ScreenSnapNotificationManager(
serviceContext = this,
serviceClass = ScreenRecorderService::class.java,
screenRecorderServiceClass = ScreenRecorderService::class.java,
)
return notificationManager.handleIntent(
intent = intent,
onStartRecording = { onStartRecording(intent) },
onPauseRecording = ::onPauseRecording,
onResumeRecording = ::onResumeRecording,
onStopRecording = ::onStopRecording,
onLaunchCamera = {}
)
}

Expand Down Expand Up @@ -88,6 +90,7 @@ class ScreenRecorderService : Service() {
}

private fun onStopRecording() {
stopService(Intent(this, FloatingCameraService::class.java))
stopSelf()
}

Expand Down
2 changes: 2 additions & 0 deletions core_screen_recorder/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
<string name="pause">Pause</string>
<string name="resume">Resume</string>
<string name="stop">Stop</string>
<string name="start">Start</string>
<string name="close">Close</string>
</resources>
5 changes: 5 additions & 0 deletions core_ui/src/main/res/drawable/baseline_cancel_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>

</vector>
5 changes: 5 additions & 0 deletions core_ui/src/main/res/drawable/record.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>

</vector>

0 comments on commit 3f2976f

Please sign in to comment.