Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
icefields committed Dec 17, 2023
0 parents commit 99e2d41
Show file tree
Hide file tree
Showing 82 changed files with 2,498 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Power-Ampache-2
1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
154 changes: 154 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import java.util.Properties

plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("kotlin-kapt")
id("dagger.hilt.android.plugin")
id("kotlin-parcelize")
id("com.google.devtools.ksp")
}

val composeVersion = rootProject.extra.get("compose_version") as String
val retrofit2Version = rootProject.extra.get("retrofit2_version") as String
val coroutinesVersion = rootProject.extra.get("coroutines_version") as String
val exoplayerVersion = rootProject.extra.get("exoplayer_version") as String

val localProperties = Properties()
localProperties.load(project.rootProject.file("local.properties").inputStream())

android {
namespace = "luci.sixsixsix.powerampache2"
compileSdk = 34

defaultConfig {
applicationId = "luci.sixsixsix.powerampache2"
minSdk = 28
targetSdk = 34
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}

compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

kotlinOptions {
jvmTarget = "1.8"
}

buildFeatures {
compose = true
buildConfig = true
}

composeOptions {
kotlinCompilerExtensionVersion = composeVersion
}

packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}

dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.8.2")

// Compose dependencies
implementation("androidx.compose.ui:ui:$composeVersion")
implementation("androidx.compose.material:material-icons-extended:1.5.4")
implementation("androidx.compose.ui:ui-tooling-preview:$composeVersion")
implementation("androidx.compose.material3:material3:1.1.2")
implementation("androidx.compose.ui:ui-graphics:$composeVersion")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
implementation("com.google.accompanist:accompanist-flowlayout:0.17.0")
implementation("androidx.paging:paging-compose:3.3.0-alpha02")
implementation("androidx.activity:activity-compose:1.8.2")
implementation("com.google.accompanist:accompanist-swiperefresh:0.24.2-alpha")
// DO NOT INCLUDE implementation("androidx.compose.material:material:$composeVersion")

// Compose Nav Destinations
implementation("io.github.raamcosta.compose-destinations:core:1.1.2-beta")
implementation("androidx.media3:media3-ui:1.2.0")
ksp("io.github.raamcosta.compose-destinations:ksp:1.1.2-beta")

// coroutines in Android
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutinesVersion")

// ExoPlayer
// api("com.google.android.exoplayer:exoplayer-core:$exoplayerVersion")
// api("com.google.android.exoplayer:exoplayer-ui:$exoplayerVersion")
// api("com.google.android.exoplayer:extension-mediasession:$exoplayerVersion")
val media3_version = "1.2.0"

// For media playback using ExoPlayer
implementation("androidx.media3:media3-exoplayer:$media3_version")
// Common functionality for media database components
implementation("androidx.media3:media3-database:$media3_version")
// Common functionality for media decoders
implementation("androidx.media3:media3-decoder:$media3_version")
// Common functionality for loading data
implementation("androidx.media3:media3-datasource:$media3_version")
// Common functionality used across multiple media libraries
implementation("androidx.media3:media3-common:1.2.0")
implementation("com.google.android.exoplayer:extension-mediasession:2.19.1")

// Glide
implementation("com.github.bumptech.glide:glide:4.15.1")
ksp("com.github.bumptech.glide:compiler:4.15.1")

//Dagger - Hilt
implementation("com.google.dagger:hilt-android:2.48")
kapt("com.google.dagger:hilt-android-compiler:2.48")
kapt("androidx.hilt:hilt-compiler:1.1.0")
implementation("androidx.hilt:hilt-navigation-compose:1.1.0")
//implementation("androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03")

// Retrofit
implementation("com.squareup.retrofit2:retrofit:$retrofit2Version")
//implementation("com.squareup.retrofit2:converter-moshi:$retrofit2Version")
implementation("com.squareup.retrofit2:converter-gson:$retrofit2Version")
implementation("com.squareup.okhttp3:okhttp:5.0.0-alpha.9")
implementation("com.squareup.okhttp3:logging-interceptor:4.10.0")
// JSON serialization
implementation("com.google.code.gson:gson:2.10")

// Room
implementation("androidx.room:room-runtime:2.6.1")
ksp("androidx.room:room-compiler:2.6.1")
// Kotlin Extensions and Coroutines support for Room
implementation("androidx.room:room-ktx:2.6.1")

testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.compose.ui:ui-test-junit4:$composeVersion")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")

debugImplementation("androidx.compose.ui:ui-test-manifest")
debugImplementation("androidx.compose.ui:ui-tooling:$composeVersion")
}
21 changes: 21 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http:https://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package luci.sixsixsix.powerampache2

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http:https://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("luci.sixsixsix.powerampache2", appContext.packageName)
}
}
36 changes: 36 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http:https://schemas.android.com/apk/res/android"
xmlns:tools="http:https://schemas.android.com/tools">

<application
android:name=".PowerAmpache2Application"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PowerAmpache2"
tools:targetApi="31">
<activity
android:name=".presentation.MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.PowerAmpache2">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service android:name=".exoplayer.MusicService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package luci.sixsixsix.powerampache2

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class PowerAmpache2Application : Application()
10 changes: 10 additions & 0 deletions app/src/main/java/luci/sixsixsix/powerampache2/common/Constants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package luci.sixsixsix.powerampache2.common

object Constants {
const val SONG_COLLECTION = "songs"
const val MEDIA_ROOT_ID = "root_id"
const val NETWORK_ERROR = "NETWORK_ERROR"
const val UPDATE_PLAYER_POSITION_INTERVAL = 100L
const val NOTIFICATION_CHANNEL_ID = "music"
const val NOTIFICATION_ID = 1
}
18 changes: 18 additions & 0 deletions app/src/main/java/luci/sixsixsix/powerampache2/common/Event.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package luci.sixsixsix.powerampache2.common

open class Event<out T>(private val data: T) {

var hasBeenHandled = false
private set

fun getContentIfNotHandled(): T? {
return if(hasBeenHandled) {
null
} else {
hasBeenHandled = true
data
}
}

fun peekContent() = data
}
24 changes: 24 additions & 0 deletions app/src/main/java/luci/sixsixsix/powerampache2/common/Resource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package luci.sixsixsix.powerampache2.common

import java.lang.Exception

data class Resource<out T>(val status: Status, val data: T?, val message: String?) {
companion object {
fun <T> success(data: T?) = Resource(Status.SUCCESS, data, null)
fun <T> error(message: String, data: T?) = Resource(Status.ERROR, data, message)
fun <T> loading(data: T?) = Resource(Status.LOADING, data, null)
}
}

enum class Status {
SUCCESS,
ERROR,
LOADING
}


sealed class Resource2<T> (val data: T? = null, val exception: Exception? = null, val message: String? = null) {
class Success<T>(data: T) : Resource2<T>(data)
class Error<T>(data: T? = null, exception: Exception, message: String = exception.localizedMessage ?: "") : Resource2<T>(data = data, message = message, exception = exception)
class Loading<T>(val isLoading: Boolean = true) : Resource2<T>()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package luci.sixsixsix.powerampache2.data.entities

data class Song(
val mediaId: String = "",
val title: String = "",
val subtitle: String = "",
val songUrl: String = "",
val imageUrl: String = ""
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package luci.sixsixsix.powerampache2.data.remote

import android.util.Log
import com.google.firebase.firestore.FirebaseFirestore
import kotlinx.coroutines.tasks.await

class MusicDatabase {

private val firestore = FirebaseFirestore.getInstance()
private val songCollection = firestore.collection(SONG_COLLECTION)

suspend fun getAllSongs(): List<Song> {
return try {
songCollection.get().await().toObjects(Song::class.java)
} catch(e: Exception) {
emptyList()
}
}
}
39 changes: 39 additions & 0 deletions app/src/main/java/luci/sixsixsix/powerampache2/di/AppModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package luci.sixsixsix.powerampache2.di

import android.content.Context
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import luci.sixsixsix.powerampache2.exoplayer.MusicServiceConnection
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

@Singleton
@Provides
fun provideMusicServiceConnection(
@ApplicationContext context: Context
) = MusicServiceConnection(context)

@Singleton
@Provides
fun provideSwipeSongAdapter() = SwipeSongAdapter()

@Singleton
@Provides
fun provideGlideInstance(
@ApplicationContext context: Context
) = Glide.with(context).setDefaultRequestOptions(
RequestOptions()
.placeholder(R.drawable.ic_image)
.error(R.drawable.ic_image)
.diskCacheStrategy(DiskCacheStrategy.DATA)
)
}
Loading

0 comments on commit 99e2d41

Please sign in to comment.