Skip to content

Commit 2d1e958

Browse files
author
Your Name
committed
Universal IDE v2.2, VLC-style Media Player, Remove Wireless Sharing
1 parent fed6dd5 commit 2d1e958

29 files changed

Lines changed: 1798 additions & 2051 deletions

‎app/build.gradle.kts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
implementation(libs.coil.compose)
7171
implementation(libs.androidx.media3.exoplayer)
7272
implementation(libs.androidx.media3.ui)
73+
implementation(libs.androidx.media3.session)
7374
implementation(libs.commons.compress)
7475
implementation(libs.poi.ooxml)
7576
implementation(libs.poi.scratchpad)

‎app/src/main/AndroidManifest.xml‎

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,8 @@
1010
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
1111
tools:ignore="ScopedStorage" />
1212
<uses-permission android:name="android.permission.INTERNET" />
13-
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
14-
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
15-
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:targetApi="31" />
16-
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" tools:targetApi="31" />
17-
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:targetApi="31" />
18-
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
19-
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
20-
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" tools:targetApi="33" />
21-
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
22-
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
2313
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
24-
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" tools:targetApi="34" />
14+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
2515
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:targetApi="33" />
2616

2717
<application
@@ -56,12 +46,15 @@
5646
android:name="android.support.FILE_PROVIDER_PATHS"
5747
android:resource="@xml/file_paths" />
5848
</provider>
59-
6049
<service
61-
android:name=".service.FileTransferService"
50+
android:name=".player.PlaybackService"
6251
android:enabled="true"
6352
android:exported="false"
64-
android:foregroundServiceType="dataSync" />
53+
android:foregroundServiceType="mediaPlayback">
54+
<intent-filter>
55+
<action android:name="androidx.media3.session.MediaSessionService" />
56+
</intent-filter>
57+
</service>
6558
</application>
6659

67-
</manifest>
60+
</manifest>

‎app/src/main/java/com/sumitupdat/universalfileeditorviewer/data/local/AppDatabase.kt‎

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,6 @@ class Converters {
1111
@TypeConverter
1212
fun toFileCategory(value: String): FileCategory = FileCategory.valueOf(value)
1313

14-
@TypeConverter
15-
fun fromTransferStatus(value: TransferStatus): String = value.name
16-
17-
@TypeConverter
18-
fun toTransferStatus(value: String): TransferStatus = TransferStatus.valueOf(value)
19-
20-
@TypeConverter
21-
fun fromTransferType(value: TransferType): String = value.name
22-
23-
@TypeConverter
24-
fun toTransferType(value: String): TransferType = TransferType.valueOf(value)
25-
2614
@TypeConverter
2715
fun fromByteArray(value: ByteArray): String = android.util.Base64.encodeToString(value, android.util.Base64.NO_WRAP)
2816

@@ -31,14 +19,13 @@ class Converters {
3119
}
3220

3321
@Database(
34-
entities = [FavoriteFile::class, RecentFile::class, IndexedFile::class, TransferEntity::class, VaultFileEntity::class, VaultAuditLog::class],
35-
version = 6,
22+
entities = [FavoriteFile::class, RecentFile::class, IndexedFile::class, VaultFileEntity::class, VaultAuditLog::class],
23+
version = 7,
3624
exportSchema = false
3725
)
3826
@TypeConverters(Converters::class)
3927
abstract class AppDatabase : RoomDatabase() {
4028
abstract fun fileDao(): FileDao
41-
abstract fun transferDao(): TransferDao
4229
abstract fun vaultDao(): VaultFileDao
4330

4431
companion object {

‎app/src/main/java/com/sumitupdat/universalfileeditorviewer/data/local/TransferDao.kt‎

Lines changed: 0 additions & 34 deletions
This file was deleted.

‎app/src/main/java/com/sumitupdat/universalfileeditorviewer/data/local/TransferEntity.kt‎

Lines changed: 0 additions & 27 deletions
This file was deleted.

‎app/src/main/java/com/sumitupdat/universalfileeditorviewer/data/local/UserPreferences.kt‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@ data class UserPreferences(
2727
val autoLockTimeoutMinutes: Int = 5,
2828
val secureDelete: Boolean = false,
2929

30-
// Wireless
31-
val autoReceiveFiles: Boolean = false,
32-
val backgroundTransfers: Boolean = true,
33-
val deviceDiscovery: Boolean = true,
34-
3530
// Language & Region
3631
val language: String = "System",
3732
val dateFormat: String = "dd/MM/yyyy",

‎app/src/main/java/com/sumitupdat/universalfileeditorviewer/data/repository/TransferRepository.kt‎

Lines changed: 0 additions & 34 deletions
This file was deleted.

‎app/src/main/java/com/sumitupdat/universalfileeditorviewer/di/DatabaseModule.kt‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.sumitupdat.universalfileeditorviewer.di
33
import android.content.Context
44
import com.sumitupdat.universalfileeditorviewer.data.local.AppDatabase
55
import com.sumitupdat.universalfileeditorviewer.data.local.FileDao
6-
import com.sumitupdat.universalfileeditorviewer.data.local.TransferDao
76
import com.sumitupdat.universalfileeditorviewer.data.local.VaultFileDao
87
import dagger.Module
98
import dagger.Provides
@@ -27,11 +26,6 @@ object DatabaseModule {
2726
return database.fileDao()
2827
}
2928

30-
@Provides
31-
fun provideTransferDao(database: AppDatabase): TransferDao {
32-
return database.transferDao()
33-
}
34-
3529
@Provides
3630
fun provideVaultDao(database: AppDatabase): VaultFileDao {
3731
return database.vaultDao()
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package com.sumitupdat.universalfileeditorviewer.player
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.*
5+
import androidx.compose.foundation.shape.RoundedCornerShape
6+
import androidx.compose.material.icons.Icons
7+
import androidx.compose.material.icons.automirrored.filled.*
8+
import androidx.compose.material.icons.filled.*
9+
import androidx.compose.material3.*
10+
import androidx.compose.runtime.*
11+
import androidx.compose.ui.Alignment
12+
import androidx.compose.ui.Modifier
13+
import androidx.compose.ui.draw.clip
14+
import androidx.compose.ui.text.font.FontWeight
15+
import androidx.compose.ui.text.style.TextAlign
16+
import androidx.compose.ui.unit.dp
17+
import androidx.compose.ui.unit.sp
18+
import androidx.hilt.navigation.compose.hiltViewModel
19+
import java.io.File
20+
21+
@Composable
22+
fun AudioPlayerScreen(
23+
file: File,
24+
onBack: () -> Unit,
25+
viewModel: PlayerViewModel = hiltViewModel()
26+
) {
27+
val uiState by viewModel.uiState.collectAsState()
28+
29+
LaunchedEffect(file) {
30+
viewModel.playFile(file, isVideo = false)
31+
}
32+
33+
Column(
34+
modifier = Modifier
35+
.fillMaxSize()
36+
.background(MaterialTheme.colorScheme.background)
37+
.padding(24.dp),
38+
horizontalAlignment = Alignment.CenterHorizontally
39+
) {
40+
// Top Navigation
41+
Row(
42+
modifier = Modifier.fillMaxWidth(),
43+
verticalAlignment = Alignment.CenterVertically
44+
) {
45+
IconButton(onClick = onBack) {
46+
Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back")
47+
}
48+
Text(
49+
"Now Playing",
50+
style = MaterialTheme.typography.titleMedium,
51+
modifier = Modifier.weight(1f),
52+
textAlign = TextAlign.Center
53+
)
54+
IconButton(onClick = { /* Equalizer */ }) {
55+
Icon(Icons.Default.Equalizer, "Equalizer")
56+
}
57+
IconButton(onClick = { /* Sleep Timer */ }) {
58+
Icon(Icons.Default.Timer, "Sleep Timer")
59+
}
60+
}
61+
62+
Spacer(modifier = Modifier.height(48.dp))
63+
64+
// Large Album Art / Icon
65+
Box(
66+
modifier = Modifier
67+
.size(300.dp)
68+
.clip(RoundedCornerShape(32.dp))
69+
.background(MaterialTheme.colorScheme.primaryContainer),
70+
contentAlignment = Alignment.Center
71+
) {
72+
Icon(
73+
Icons.Default.MusicNote,
74+
null,
75+
modifier = Modifier.size(150.dp),
76+
tint = MaterialTheme.colorScheme.primary
77+
)
78+
}
79+
80+
Spacer(modifier = Modifier.height(48.dp))
81+
82+
// Title and Subtitle
83+
Text(
84+
text = uiState.fileName,
85+
style = MaterialTheme.typography.headlineSmall,
86+
fontWeight = FontWeight.Bold,
87+
textAlign = TextAlign.Center,
88+
maxLines = 1
89+
)
90+
Text(
91+
text = "Unknown Artist",
92+
style = MaterialTheme.typography.bodyLarge,
93+
color = MaterialTheme.colorScheme.onSurfaceVariant
94+
)
95+
96+
Spacer(modifier = Modifier.weight(1f))
97+
98+
// Progress Slider
99+
Column(modifier = Modifier.fillMaxWidth()) {
100+
Slider(
101+
value = uiState.currentPosition.toFloat(),
102+
onValueChange = { viewModel.seekTo(it.toLong()) },
103+
valueRange = 0f..(uiState.duration.toFloat().coerceAtLeast(1f)),
104+
colors = SliderDefaults.colors(
105+
thumbColor = MaterialTheme.colorScheme.primary,
106+
activeTrackColor = MaterialTheme.colorScheme.primary
107+
)
108+
)
109+
Row(
110+
modifier = Modifier.fillMaxWidth(),
111+
horizontalArrangement = Arrangement.SpaceBetween
112+
) {
113+
Text(formatTime(uiState.currentPosition), style = MaterialTheme.typography.labelSmall)
114+
Text(formatTime(uiState.duration), style = MaterialTheme.typography.labelSmall)
115+
}
116+
}
117+
118+
Spacer(modifier = Modifier.height(24.dp))
119+
120+
// Playback Controls
121+
Row(
122+
modifier = Modifier.fillMaxWidth(),
123+
horizontalArrangement = Arrangement.SpaceEvenly,
124+
verticalAlignment = Alignment.CenterVertically
125+
) {
126+
IconButton(onClick = { viewModel.toggleShuffle() }) {
127+
Icon(
128+
Icons.Default.Shuffle,
129+
"Shuffle",
130+
tint = if (uiState.shuffleMode) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
131+
)
132+
}
133+
IconButton(onClick = { /* Previous */ }) {
134+
Icon(Icons.Default.SkipPrevious, "Previous", modifier = Modifier.size(48.dp))
135+
}
136+
FilledIconButton(
137+
onClick = { viewModel.togglePlayPause() },
138+
modifier = Modifier.size(72.dp),
139+
shape = RoundedCornerShape(24.dp)
140+
) {
141+
Icon(
142+
if (uiState.isPlaying) Icons.Default.Pause else Icons.Default.PlayArrow,
143+
"Play/Pause",
144+
modifier = Modifier.size(36.dp)
145+
)
146+
}
147+
IconButton(onClick = { /* Next */ }) {
148+
Icon(Icons.Default.SkipNext, "Next", modifier = Modifier.size(48.dp))
149+
}
150+
IconButton(onClick = { viewModel.toggleRepeat() }) {
151+
Icon(
152+
when (uiState.repeatMode) {
153+
androidx.media3.common.Player.REPEAT_MODE_ONE -> Icons.Default.RepeatOne
154+
androidx.media3.common.Player.REPEAT_MODE_ALL -> Icons.Default.Repeat
155+
else -> Icons.Default.Repeat
156+
},
157+
"Repeat",
158+
tint = if (uiState.repeatMode != androidx.media3.common.Player.REPEAT_MODE_OFF) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
159+
)
160+
}
161+
}
162+
163+
Spacer(modifier = Modifier.height(48.dp))
164+
}
165+
}

0 commit comments

Comments
 (0)