Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release]: release 0.0.2 작업 finish #51

Merged
merged 7 commits into from
Jan 7, 2024
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
1 change: 1 addition & 0 deletions app/src/main/java/com/hmh/hamyeonham/SampleActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class SampleActivity : AppCompatActivity() {
initSplashAnimation(splashScreen)
setContentView(binding.root)
startActivity(Intent(this, OnBoardingActivity::class.java))
finish()
}

private fun initSplashAnimation(splashScreen: SplashScreen) {
Expand Down
17 changes: 17 additions & 0 deletions app/src/main/java/com/hmh/hamyeonham/di/NavigatorModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.hmh.hamyeonham.di

import com.hmh.hamyeonham.common.navigation.NavigationProvider
import com.hmh.hamyeonham.navigation.DefaultNavigationProvider
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
interface NavigatorModule {
@Binds
@Singleton
fun bindNavigator(navigator: DefaultNavigationProvider): NavigationProvider
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.hmh.hamyeonham.navigation

import android.content.Context
import android.content.Intent
import com.hmh.hamyeonham.common.navigation.NavigationProvider
import com.hmh.hamyeonham.feature.login.LoginActivity
import com.hmh.hamyeonham.feature.login.UserInfoActivity
import com.hmh.hamyeonham.feature.onboarding.OnBoardingActivity
import com.hmh.hamyeonham.statistics.StaticsActivity
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

class DefaultNavigationProvider @Inject constructor(
@ApplicationContext private val context: Context
) : NavigationProvider {
override fun toOnboarding(): Intent {
return Intent(context, OnBoardingActivity::class.java)
}

override fun toLogin(): Intent {
return Intent(context, LoginActivity::class.java)
}

override fun toUserInfo(): Intent {
return Intent(context, UserInfoActivity::class.java)
}

override fun toStatics(): Intent {
return Intent(context, StaticsActivity::class.java)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import android.content.Intent

interface NavigationProvider {
fun toOnboarding(): Intent
fun toLicense(): Intent
fun toHome(): Intent
fun toAlbumList(albumId: Long): Intent
fun toSignUp(): Intent
fun toLogin(): Intent
fun toUserInfo(): Intent
fun toStatics(): Intent
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,12 @@ fun getCurrentDayStartEndEpochMillis(): Pair<Long, Long> {
return Pair(startOfDay, endOfDay)
}

fun convertMillisecondsToMinute(ms: Long) = TimeUnit.MILLISECONDS.toMinutes(ms)

fun convertTimeToString(time: Long): String {
val hour = convertMillisecondsToMinute(time) / 60
val min = convertMillisecondsToMinute(time) % 60
var result = ""
if (hour > 0) result = result.plus("$hour" + "시간")
if (min >= 0) result = result.plus("$min" + "분")
return result
val hours = TimeUnit.MILLISECONDS.toHours(time)
val minutes = TimeUnit.MILLISECONDS.toMinutes(time) % 60

return buildString {
if (hours > 0) append("$hours 시간")
if (minutes > 0 || hours == 0L) append(" $minutes 분")
}.trim()
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
package com.hmh.hamyeonham.usagestats.datasource

import com.hmh.hamyeonham.usagestats.model.UsageGoalModel
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import javax.inject.Inject

@Module
@InstallIn(SingletonComponent::class)
class UsageGoalsDataSource {
@Provides
@Singleton
class UsageGoalsDataSource @Inject constructor() {
fun getUsageGoals(): List<UsageGoalModel> {
return listOf(
UsageGoalModel("total", 201519990),
UsageGoalModel("com.kakao.talk", 15686 * 2),
UsageGoalModel("com.google.android.gms", 7134),
UsageGoalModel("com.google.android.youtube", 71349),
UsageGoalModel("com.android.chrome", 39445),
UsageGoalModel("total", 9459489),
UsageGoalModel("com.kakao.talk", 10737116),
UsageGoalModel("com.google.android.gms", 10607821),
UsageGoalModel("com.google.android.youtube", 7409658),
UsageGoalModel("com.android.chrome", 9346527),
)
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package com.hmh.hamyeonham.usagestats.repository

import com.hmh.hamyeonham.usagestats.datasource.UsageGoalsDataSource
import com.hmh.hamyeonham.usagestats.model.UsageGoal
import com.hmh.hamyeonham.usagestats.model.UsageGoalModel
import javax.inject.Inject

class DefaultUsageGoalsRepository @Inject constructor(
private val usageGoalList: List<UsageGoalModel>,
private val usageGoalsDataSource: UsageGoalsDataSource
) : UsageGoalsRepository {
override fun getUsageGoals(): List<UsageGoal> {
return usageGoalList.map {
return usageGoalsDataSource.getUsageGoals().map {
UsageGoal(it.packageName, it.goalTime)
}
}

override fun getUsageGoalTime(packageName: String): Long {
return usageGoalList.firstOrNull { it.packageName == packageName }?.goalTime ?: 0
return usageGoalsDataSource.getUsageGoals()
.firstOrNull { it.packageName == packageName }?.goalTime ?: 0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,9 @@ data class UsageStatAndGoal(
) {
private val challengeSuccess: Boolean = (goalTime - totalTimeInForeground) >= 0
val timeLeft: Long by lazy {
if (challengeSuccess) {
goalTime - totalTimeInForeground
} else {
0L
}
if (challengeSuccess) goalTime - totalTimeInForeground else 0L
}
val usedPercentage: Int by lazy {
if (challengeSuccess) {
(totalTimeInForeground * 100 / goalTime).toInt()
} else {
100
}
if (challengeSuccess) (totalTimeInForeground * 100 / goalTime).toInt() else 100
}
}
Original file line number Diff line number Diff line change
@@ -1,46 +1,61 @@
package com.hmh.hamyeonham.usagestats.usecase

import com.hmh.hamyeonham.usagestats.model.UsageStatAndGoal
import com.hmh.hamyeonham.usagestats.repository.UsageGoalsRepository
import com.hmh.hamyeonham.usagestats.repository.UsageStatsRepository
import javax.inject.Inject

class StaticsUseCase @Inject constructor(
private val usageStatsRepository: UsageStatsRepository,
private val usageGoalsRepository: UsageGoalsRepository,
) {
fun getUsageStatsAndGoals(
startTime: Long,
endTime: Long,
): List<UsageStatAndGoal> {
val totalUsage = getTotalUsage(startTime, endTime)
val usageForSelectedApps = getUsageStatsAndGoalsForSelectedApps(startTime, endTime)
val totalUsageStatAndGoal =
UsageStatAndGoal("total", totalUsage, usageGoalsRepository.getUsageGoalTime("total"))
return listOf(totalUsageStatAndGoal) + usageForSelectedApps
}

private fun getUsageStatsAndGoalsForSelectedApps(
startTime: Long,
endTime: Long,
): List<UsageStatAndGoal> {
val appList = getSelectedAppList()
return usageStatsRepository.getUsageTimeForPackages(startTime, endTime, appList).map {
UsageStatAndGoal(
it.packageName,
it.totalTimeInForeground,
usageGoalsRepository.getUsageGoalTime(it.packageName),
)
}
}

private fun getTotalUsage(
startTime: Long,
endTime: Long,
): Long = usageStatsRepository.getUsageStats(startTime, endTime).sumOf {
it.totalTimeInForeground
}

private fun getSelectedAppList(): List<String> =
usageGoalsRepository.getUsageGoals().map { it.packageName }
}
package com.hmh.hamyeonham.usagestats.usecase

import com.hmh.hamyeonham.usagestats.model.UsageStatAndGoal
import com.hmh.hamyeonham.usagestats.repository.UsageGoalsRepository
import com.hmh.hamyeonham.usagestats.repository.UsageStatsRepository
import javax.inject.Inject

class GetUsageStatsListUseCase @Inject constructor(
private val usageStatsRepository: UsageStatsRepository,
private val usageGoalsRepository: UsageGoalsRepository,
) {

companion object {
private const val TOTAL = "total"
}

fun getUsageStatsAndGoals(
startTime: Long,
endTime: Long,
): List<UsageStatAndGoal> {
val totalUsage = getTotalUsage(startTime, endTime)
val usageForSelectedApps = getUsageStatsAndGoalsForSelectedApps(startTime, endTime)
val totalUsageStatAndGoal =
UsageStatAndGoal(TOTAL, totalUsage, usageGoalsRepository.getUsageGoalTime(TOTAL))
return listOf(totalUsageStatAndGoal) + usageForSelectedApps
}

private fun getUsageStatsAndGoalsForSelectedApps(
startTime: Long,
endTime: Long,
): List<UsageStatAndGoal> {
val appList = getSelectedPackageList()
return usageStatsRepository.getUsageTimeForPackages(startTime, endTime, appList)
.map {
createUsageStatAndGoal(
it.packageName,
it.totalTimeInForeground,
it.packageName
)
}
}

private fun getTotalUsage(
startTime: Long,
endTime: Long,
): Long = usageStatsRepository.getUsageStats(startTime, endTime).sumOf {
it.totalTimeInForeground
}

private fun getSelectedPackageList(): List<String> =
usageGoalsRepository.getUsageGoals().map { it.packageName }.distinct()

private fun createUsageStatAndGoal(
packageName: String,
totalTimeInForeground: Long,
goalKey: String
): UsageStatAndGoal {
val goalTime = usageGoalsRepository.getUsageGoalTime(goalKey)
return UsageStatAndGoal(packageName, totalTimeInForeground, goalTime)
}
}
7 changes: 6 additions & 1 deletion feature/login/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ android {
}

dependencies {

// Common
implementation(projects.core.common)

// kakao
implementation(libs.kakao.login)

implementation(libs.dot.indicator)
// coil
implementation(libs.coil.core)

// dot indicator
implementation(libs.dot.indicator)
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
package com.hmh.hamyeonham.feature.login

import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import com.hmh.hamyeonham.common.context.toast
import com.hmh.hamyeonham.common.navigation.NavigationProvider
import com.hmh.hamyeonham.feature.login.data.DummyImage
import com.hmh.hamyeonham.feature.login.databinding.ActivityLoginBinding
import com.kakao.sdk.auth.model.OAuthToken
import com.kakao.sdk.common.model.ClientError
import com.kakao.sdk.common.model.ClientErrorCause
import com.kakao.sdk.user.UserApiClient
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

@AndroidEntryPoint
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding

private val loginViewModel: LoginViewModel by viewModels()
private lateinit var loginViewPagerAdapter: LoginViewPagerAdapter

@Inject
lateinit var navigationProvider: NavigationProvider

// 삭제 예정
private val dummyImageList = listOf(
DummyImage(
Expand Down Expand Up @@ -86,7 +93,7 @@ class LoginActivity : AppCompatActivity() {
}

private fun moveToUserInfoActivity() {
startActivity(Intent(this, UserInfoActivity::class.java))
startActivity(navigationProvider.toStatics())
finish()
}
}
1 change: 0 additions & 1 deletion feature/onboarding/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ android {

dependencies {
implementation(projects.core.common)
implementation(projects.feature.login)
}
5 changes: 5 additions & 0 deletions feature/onboarding/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

Expand All @@ -25,5 +26,9 @@
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>

<activity
android:name=".LockActivity"
android:exported="true" />
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.hmh.hamyeonham.feature.onboarding

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.hmh.hamyeonham.common.context.toast
import com.hmh.hamyeonham.common.view.viewBinding
import com.hmh.hamyeonham.feature.onboarding.databinding.ActivityLockBinding

class LockActivity : AppCompatActivity() {
private val binding by viewBinding(ActivityLockBinding::inflate)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)

binding.btnLock.setOnClickListener {
toast("유튜브 잠금 설정 완료")
}
}
}
Loading