Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# https://editorconfig.org
root = true

[*.{kt,kts}]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
ktlint_function_naming_ignore_when_annotated_with = Composable

[*.xml]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

# Disable copyright headers for ALL XML files
[app/src/main/res/**/*.xml]
ij_formatter_off = true
Empty file.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
<img src="https://img.shields.io/badge/Kotlin-7F52FF?logo=kotlin&logoColor=white" alt="Kotlin">
<img src="https://img.shields.io/badge/Jetpack_Compose-03D2A8?logo=jetpack&logoColor=white" alt="Jetpack Compose">
<img src="https://img.shields.io/badge/Open%20Source-89CFF0?logo=github&logoColor=white" alt="Open Source">
<img src="https://img.shields.io/github/workflow/status/itsPronay/napify/Build%20Check?label=Checks%20Passing&logo=github&logoColor=white" alt="Checks Passing">
<img src="https://img.shields.io/github/workflow/status/itsPronay/blankee/Build%20Check?label=Checks%20Passing&logo=github&logoColor=white" alt="Checks Passing">
</p>

<div style="display: flex; justify-content: center; width: 100%;">
<h1># 🎵 Napify</h1>
<h1># 🎵 Blankee</h1>
</div>

Napify is a **sound-based productivity and relaxation app** designed to help you:
Blankee is a **sound-based productivity and relaxation app** designed to help you:
- Focus better
- Boost productivity
- Fall asleep in noisy environments
Expand All @@ -32,11 +32,11 @@ Napify is a **sound-based productivity and relaxation app** designed to help you
## 📥 Download Now

**📲 Available on Google Play!**
[![Get it on Google Play](https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=com.pronaycoding.blanket_mobile)
[![Get it on Google Play](https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=com.pronaycoding.blankee)

Or download the latest APK from GitHub:

1. **Go to the [GitHub Actions page](https://github.com/itsPronay/napify/actions)**
1. **Go to the [GitHub Actions page](https://github.com/itsPronay/blankee/actions)**
2. Click on the **latest workflow run** under the **"Build Check"** section
3. Scroll down to the **Artifacts** section
4. Download **app-debug.apk** or **app-release.apk**
Expand All @@ -52,17 +52,17 @@ We welcome open-source contributions! Feel free to:
- Report **issues**
- Suggest **new features**

Join us in making Napify better!
Join us in making Blankee better!

## 💡 Inspiration

Napify is inspired by **[Blanket](https://github.com/rafaelmardojai/blanket)**, a GNOME application developed by **Rafael Mardojai**.
Blankee is inspired by **[Blanket](https://github.com/rafaelmardojai/blanket)**, a GNOME application developed by **Rafael Mardojai**.
This project aims to bring a **similar experience to Android devices**.

> \[!Note]
> The sounds used in this app are **not original**. They have been **sourced from others**.
> Special thanks to the **original creators** of these sounds for making them available.
> Please see [SOUNDS_LICENSING.md](https://github.com/itsPronay/napify/blob/play_store/SOUNDS_LICENSING.md) for more info.
> Please see [SOUNDS_LICENSING.md](https://github.com/itsPronay/blankee/blob/play_store/SOUNDS_LICENSING.md) for more info.

🌙✨ **Enjoy Napify!**
🌙✨ **Enjoy Blankee!**
📬 *Have feedback? Open an issue or contribute!*
3 changes: 2 additions & 1 deletion app/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/build
.kotlin/
local.properties
local.properties
google-services.json
7 changes: 0 additions & 7 deletions app/AppModule.kt

This file was deleted.

75 changes: 42 additions & 33 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid)

id("kotlin-kapt")
id("com.google.dagger.hilt.android")
alias(libs.plugins.google.ksp)
alias(libs.plugins.compose.compiler)

//hilt
// id ("kotlin-kapt")
// id("com.google.dagger.hilt.android")
alias(libs.plugins.google.gms.google.services)
alias(libs.plugins.google.firebase.crashlytics)
}

android {
namespace = "com.pronaycoding.blanket_mobile"
namespace = "com.pronaycoding.blankee"
compileSdk = 35

defaultConfig {
applicationId = "com.pronaycoding.blanket_mobile"
applicationId = "com.pronaycoding.blankee"
minSdk = 24
targetSdk = 34
versionCode = 3
Expand All @@ -29,12 +25,16 @@ android {
}

buildTypes {
debug {
buildConfigField("boolean", "CUSTOM_SOUNDS_PREMIUM_LOCKED", "false")
}
release {
isShrinkResources = true
isMinifyEnabled = true
buildConfigField("boolean", "CUSTOM_SOUNDS_PREMIUM_LOCKED", "true")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
"proguard-rules.pro",
)
}
}
Expand All @@ -47,6 +47,7 @@ android {
}
buildFeatures {
compose = true
buildConfig = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
Expand All @@ -56,11 +57,20 @@ android {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}

// Lint is currently hanging during `lintAnalyzeDebug` / `lintVitalAnalyzeRelease`.
// Keep CI/builds unblocked while we investigate root cause.
lint {
checkReleaseBuilds = false
abortOnError = false
}
}

dependencies {

implementation(libs.androidx.core.ktx)
implementation("androidx.datastore:datastore-preferences:1.1.1")
implementation("androidx.media:media:1.7.0")
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
Expand All @@ -70,6 +80,7 @@ dependencies {
implementation(libs.androidx.material3)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.lifecycle.runtime.compose.android)
implementation(libs.firebase.crashlytics)
// implementation(libs.androidx.material3.android)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
Expand All @@ -79,34 +90,32 @@ dependencies {
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)

//navigation
val nav_version = "2.7.7"
implementation("androidx.navigation:navigation-compose:$nav_version")

//Exoplayer
implementation("androidx.media3:media3-exoplayer:1.3.1")
implementation("androidx.media3:media3-exoplayer-dash:1.3.1")
implementation("androidx.media3:media3-ui:1.3.1")
// navigation
implementation(libs.androidx.navigation.compose)

// Exoplayer
implementation(libs.androidx.media3.exoplayer)
implementation(libs.androidx.media3.exoplayer.dash)
implementation(libs.androidx.media3.ui)

//await
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0")
// await
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.androidx.lifecycle.viewmodel.ktx)
// implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.4.0")

// //hilt
implementation("com.google.dagger:hilt-android:2.54")
kapt("com.google.dagger:hilt-android-compiler:2.54")
implementation(libs.androidx.hilt.navigation.compose)
// Koin
implementation(libs.koin.android)
implementation(libs.koin.androidx.compose)

// extra icons
implementation("androidx.compose.material:material-icons-extended:1.5.1")
implementation(libs.androidx.compose.material.icons.extended)

// implementation("com.google.dagger:hilt-android:2.44")
// kapt("com.google.dagger:hilt-android-compiler:2.44")
}
// Room Database (KSP avoids Kotlin 2.x + kapt processor issues)
implementation(libs.androidx.room.runtime)
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.room.ktx)

//kapt {
// correctErrorTypes = true
//}
implementation(libs.billing)
implementation(libs.billing.ktx)
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.pronaycoding.blanket_mobile
package com.pronaycoding.blankee

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

import androidx.test.platform.app.InstrumentationRegistry
import junit.framework.TestCase.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand All @@ -19,6 +17,6 @@ class ExampleInstrumentedTest {
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.pronaycoding.blanket_mobile", appContext.packageName)
assertEquals("com.pronaycoding.blankee", appContext.packageName)
}
}
}
21 changes: 19 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />


<application
Expand All @@ -11,10 +15,14 @@
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:localeConfig="@xml/locales_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Blanketmobile"
tools:targetApi="31">
tools:targetApi="35">
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false" />
<activity
android:name=".MainActivity"
android:exported="true"
Expand All @@ -26,6 +34,15 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name=".core.service.playback.BlankeeMediaPlaybackService"
android:exported="false"
android:foregroundServiceType="mediaPlayback" />

<receiver
android:name=".core.service.playback.MediaPlaybackActionReceiver"
android:exported="false" />
</application>

</manifest>
Binary file modified app/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions app/src/main/java/com/pronaycoding/blankee/App.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.pronaycoding.blankee

import android.app.Application
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.pronaycoding.blankee.core.service.billing.PlayBillingManager
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.GlobalContext
import org.koin.core.context.startKoin
import org.koin.core.logger.Level

/**
* Blankee Application class.
*
* This is the entry point for the entire application. It initializes:
* - Firebase Crashlytics for error tracking and reporting
* - Koin dependency injection framework with all modules
* - Play Billing Manager for in-app purchase handling
*
* Extends [Application] to provide application-level lifecycle methods.
* Called once when the app process is created.
*
* @see KoinModule for dependency injection configuration
* @see PlayBillingManager for billing initialization
*/
class App : Application() {
/**
* Called when the application is starting.
*
* This method:
* 1. Initializes Firebase Crashlytics (enabled only in release builds for privacy)
* 2. Starts Koin with all configured modules
* 3. Initializes PlayBillingManager for handling in-app purchases
*
* Debug logging for Koin is enabled in debug builds to help diagnose DI issues.
*/
override fun onCreate() {
super.onCreate()

// Initialize Firebase Crashlytics
FirebaseCrashlytics
.getInstance()
.setCrashlyticsCollectionEnabled(BuildConfig.BUILD_TYPE == "release")

// Start Koin dependency injection framework
startKoin {
if (BuildConfig.DEBUG) {
androidLogger(Level.DEBUG) // Enable debug logging only in debug builds
}
androidContext(this@App)
modules(KoinModule.allModules)
}

// Initialize Play Billing for premium features
GlobalContext.get().get<PlayBillingManager>().start()
}
}
Loading
Loading