diff --git a/.idea/misc.xml b/.idea/misc.xml index df3e55b..d015193 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,15 +3,43 @@ diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0e138df..c9778fb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,6 +18,10 @@ android { versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + aaptOptions { + noCompress "tflite" + } } buildTypes { @@ -42,12 +46,13 @@ android { } dependencies { - implementation 'androidx.core:core-ktx:1.7.0' - implementation 'androidx.appcompat:appcompat:1.4.1' - implementation 'com.google.android.material:material:1.6.0' + implementation 'androidx.core:core-ktx:1.8.0' + implementation 'androidx.appcompat:appcompat:1.4.2' + implementation 'com.google.android.material:material:1.6.1' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'org.tensorflow:tensorflow-lite-support:0.1.0' - implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0' + implementation 'org.tensorflow:tensorflow-lite-support:0.3.0' + implementation 'org.tensorflow:tensorflow-lite-metadata:0.3.0' + implementation 'org.tensorflow:tensorflow-lite:2.8.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' @@ -101,7 +106,11 @@ dependencies { def viewPager2 = "1.0.0" implementation "androidx.viewpager2:viewpager2:$viewPager2" - implementation 'com.ismaeldivita.chipnavigation:chip-navigation-bar:1.3.4' + // Required Library Dexter + implementation 'com.karumi:dexter:6.2.3' + + // Shimmer + implementation 'com.facebook.shimmer:shimmer:0.5.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ea2b9f5..26e8b20 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,13 +5,11 @@ - - - @@ -36,17 +34,28 @@ android:screenOrientation="portrait" tools:ignore="LockedOrientationActivity" /> - - + + + - + + + + + + + + \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..0aca6fc Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/com/candra/projectcapstone/activity/home/ListDetailScan.kt b/app/src/main/java/com/candra/projectcapstone/activity/home/ListDetailScan.kt new file mode 100644 index 0000000..dff4ba8 --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/activity/home/ListDetailScan.kt @@ -0,0 +1,139 @@ +package com.candra.projectcapstone.activity.home + +import android.annotation.SuppressLint +import android.content.Intent +import android.graphics.BitmapFactory +import android.os.Bundle +import android.view.View +import android.widget.ImageView +import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.LinearLayoutManager +import coil.load +import coil.transform.CircleCropTransformation +import com.candra.projectcapstone.R +import com.candra.projectcapstone.adapter.AdapterForFear +import com.candra.projectcapstone.databinding.ResultActivityBinding +import com.candra.projectcapstone.helper.Constant +import com.candra.projectcapstone.helper.Constant.PICTURE +import com.candra.projectcapstone.helper.Constant.RESULT_SCAN_FACE +import com.candra.projectcapstone.viewmodel.ListMusicViewModel +import com.google.android.material.textview.MaterialTextView +import dagger.hilt.android.AndroidEntryPoint +import java.io.File + +@AndroidEntryPoint +class ListDetailScan: AppCompatActivity() +{ + + private lateinit var binding: ResultActivityBinding + private var getFile: File? = null + private var getIsBackCamera:Boolean = false + private val listMusicViewModel by viewModels() + private val adapterMusic by lazy { AdapterForFear() } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ResultActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + setBackgroundCardView() + setActionComponentClick() + readObserverData() + setAdapterToListDetailScan() + } + + private fun setBackgroundCardView(){ + binding.apply { + containerImageview.background = ContextCompat.getDrawable(this@ListDetailScan, R.drawable.turn_back) + } + } + + private fun setActionComponentClick(){ + binding.apply { + containerImageview.setOnClickListener { + toBackHomeFragment() + } + getResultFromCamera(imageScanUser,resultTextScanUser,textDescriptionName) + } + } + + @SuppressLint("SetTextI18n") + private fun getResultFromCamera(imageView: ImageView, textResultScan: MaterialTextView, textDescriptionResultScan: MaterialTextView){ + val resultImage = intent.getSerializableExtra(PICTURE) as File + val resultScanFace = intent.getStringExtra(RESULT_SCAN_FACE) + val convertFileToBitmap = BitmapFactory.decodeFile(resultImage.path) + + + imageView.load(convertFileToBitmap){ + transformations(CircleCropTransformation()) + } + textResultScan.text = resultScanFace + textDescriptionResultScan.text = "Lagu untuk hasil ${resultScanFace}, Selamat menikmati lagu ${resultScanFace}" + + resultScanFace?.let { setListMusicBasedResultFace(it) } + } + + private fun setListMusicBasedResultFace(resultFace: String){ + when(resultFace){ + Constant.ANGRY -> { + listMusicViewModel.getAllMusicList(Constant.ANGRY) + } + Constant.SAD -> { + listMusicViewModel.getAllMusicList(Constant.SAD) + } + Constant.DISGUST -> { + listMusicViewModel.getAllMusicList(Constant.DISGUST) + } + Constant.FEAR -> { + listMusicViewModel.getAllMusicList(Constant.FEAR) + } + Constant.HAPPY -> { + listMusicViewModel.getAllMusicList(Constant.HAPPY) + } + Constant.NEUTRAL -> { + listMusicViewModel.getAllMusicList(Constant.NEUTRAL) + } + Constant.SURPRISE -> { + listMusicViewModel.getAllMusicList(Constant.SURPRISE) + } + } + } + + private fun setAdapterToListDetailScan(){ + binding.listMusicItem.apply { + layoutManager = LinearLayoutManager(this@ListDetailScan) + adapter = adapterMusic + } + } + + private fun readObserverData(){ + listMusicViewModel.listMusicData.observe(this){ + if (it != null){ + adapterMusic.addAllDataMusic(it) + } + } + listMusicViewModel.loading.observe(this){ + showShimmerEffect(it) + } + } + + private fun showShimmerEffect(show: Boolean){ + binding.apply { + if (show){ + shimmerEffect.startShimmer() + shimmerEffect.visibility = View.VISIBLE + listMusicItem.visibility = View.GONE + }else{ + shimmerEffect.hideShimmer() + shimmerEffect.visibility = View.GONE + listMusicItem.visibility = View.VISIBLE + } + } + } + + private fun toBackHomeFragment(){ + startActivity(Intent(this@ListDetailScan,MainActivity::class.java)) + finish() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/activity/home/MainActivity.kt b/app/src/main/java/com/candra/projectcapstone/activity/home/MainActivity.kt index 77c9930..b611c0d 100644 --- a/app/src/main/java/com/candra/projectcapstone/activity/home/MainActivity.kt +++ b/app/src/main/java/com/candra/projectcapstone/activity/home/MainActivity.kt @@ -2,14 +2,32 @@ package com.candra.projectcapstone.activity.home import android.os.Bundle import androidx.appcompat.app.AppCompatActivity +import com.candra.projectcapstone.R import com.candra.projectcapstone.databinding.ActivityMainBinding +import com.candra.projectcapstone.fragment.HomeFragment +import com.candra.projectcapstone.fragment.MusicFragment +import com.candra.projectcapstone.helper.Helper +import dagger.hilt.android.AndroidEntryPoint - +@AndroidEntryPoint class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) + Helper.loadFragment(HomeFragment(),supportFragmentManager) + setBottomNavigation() + } + + private fun setBottomNavigation(){ + binding.bottomNavigation.setOnItemSelectedListener { + when(it.itemId){ + R.id.home -> Helper.loadFragment(HomeFragment(),supportFragmentManager) + R.id.music -> Helper.loadFragment(MusicFragment(),supportFragmentManager) + } + return@setOnItemSelectedListener true + } } } \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/activity/login/LoginActivity.kt b/app/src/main/java/com/candra/projectcapstone/activity/login/LoginActivity.kt deleted file mode 100644 index 85f837c..0000000 --- a/app/src/main/java/com/candra/projectcapstone/activity/login/LoginActivity.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.candra.projectcapstone.activity.login - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.candra.projectcapstone.databinding.ActivityLoginBinding -import com.candra.projectcapstone.helper.Helper - -class LoginActivity: AppCompatActivity() -{ - private lateinit var binding: ActivityLoginBinding - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityLoginBinding.inflate(layoutInflater) - setContentView(binding.root) - binding.apply { - textviewNotHaveAccount.setOnClickListener { - Helper.toNavigateRegisterActivity(this@LoginActivity) - finish() - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/activity/onboarding/ViewPagerActivity.kt b/app/src/main/java/com/candra/projectcapstone/activity/onboarding/ViewPagerActivity.kt index 466925f..f55e900 100644 --- a/app/src/main/java/com/candra/projectcapstone/activity/onboarding/ViewPagerActivity.kt +++ b/app/src/main/java/com/candra/projectcapstone/activity/onboarding/ViewPagerActivity.kt @@ -2,9 +2,7 @@ package com.candra.projectcapstone.activity.onboarding import android.os.Bundle import androidx.appcompat.app.AppCompatActivity -import androidx.fragment.app.Fragment import com.candra.projectcapstone.activity.onboarding.screen.FragmentOne -import com.candra.projectcapstone.activity.onboarding.screen.FragmentThree import com.candra.projectcapstone.activity.onboarding.screen.FragmentTwo import com.candra.projectcapstone.databinding.FragmentViewPagerBinding @@ -21,10 +19,9 @@ class ViewPagerActivity: AppCompatActivity() } private fun setFragment(){ - val fragmentList = arrayListOf( + val fragmentList = arrayListOf( FragmentOne(), FragmentTwo(), - FragmentThree() ) val adapterListFragment = ViewPagerAdapter( diff --git a/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentOne.kt b/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentOne.kt index 2b84f16..15d48f8 100644 --- a/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentOne.kt +++ b/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentOne.kt @@ -11,6 +11,8 @@ import com.candra.projectcapstone.R import com.candra.projectcapstone.databinding.FragmentScreenOneBinding import com.candra.projectcapstone.helper.Helper import com.candra.projectcapstone.helper.Helper.IMAGE_SCREEN_ONE +import com.candra.projectcapstone.helper.Helper.imageScreen +import com.candra.projectcapstone.helper.Helper.setCheckedData class FragmentOne: Fragment() { @@ -37,11 +39,11 @@ class FragmentOne: Fragment() } btnSkipScreenOne.setOnClickListener { - Helper.toScreenHome(requireActivity()) - Helper.setCheckedData(lifecycleScope,requireActivity()) + Helper.toHomeScreen(requireActivity()) + setCheckedData(lifecycleScope,requireActivity()) } - Helper.imageScreen(ivScreenOne,IMAGE_SCREEN_ONE) + imageScreen(ivScreenOne,IMAGE_SCREEN_ONE) } } diff --git a/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentThree.kt b/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentThree.kt deleted file mode 100644 index b7cd2c3..0000000 --- a/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentThree.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.candra.projectcapstone.activity.onboarding.screen - -import android.content.Intent -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.Fragment -import androidx.lifecycle.lifecycleScope -import com.candra.projectcapstone.databinding.FragmentScreenThreeBinding -import com.candra.projectcapstone.helper.Helper -import com.candra.projectcapstone.helper.Helper.IMAGE_SCREEN_THREE -import com.candra.projectcapstone.helper.LocalShared -import kotlinx.coroutines.launch - -class FragmentThree: Fragment() -{ - private var _binding: FragmentScreenThreeBinding? = null - private val binding get() = _binding!! - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View{ - _binding = FragmentScreenThreeBinding.inflate(inflater,container,false) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding.apply { - btnNextScreenOne.setOnClickListener { - Helper.toScreenHome(requireActivity()) - lifecycleScope.launch { - Helper.setCheckedData(lifecycleScope,requireActivity()) - } - } - btnSkipScreenOne.setOnClickListener { - Helper.toScreenHome(requireActivity()) - Helper.setCheckedData(lifecycleScope,requireActivity()) - } - Helper.imageScreen(ivScreenOne,IMAGE_SCREEN_THREE) - } - } - - - - override fun onDestroy() { - super.onDestroy() - _binding = null - } -} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentTwo.kt b/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentTwo.kt index ad65b0d..da2c6f0 100644 --- a/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentTwo.kt +++ b/app/src/main/java/com/candra/projectcapstone/activity/onboarding/screen/FragmentTwo.kt @@ -1,5 +1,6 @@ package com.candra.projectcapstone.activity.onboarding.screen +import android.annotation.SuppressLint import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -26,16 +27,19 @@ class FragmentTwo : Fragment() return binding.root } + @SuppressLint("SetTextI18n") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val viewPager2 = activity?.findViewById(R.id.view_pager_2) binding.apply { + btnNextScreenOne.text = "Finish" btnNextScreenOne.setOnClickListener { - viewPager2?.currentItem = 2 + Helper.toHomeScreen(requireActivity()) + Helper.setCheckedData(lifecycleScope,requireActivity()) } btnSkipScreenOne.setOnClickListener { - Helper.toScreenHome(requireActivity()) + Helper.toHomeScreen(requireActivity()) Helper.setCheckedData(lifecycleScope,requireActivity()) } Helper.imageScreen(ivScreenOne,IMAGE_SCREEN_TWO) diff --git a/app/src/main/java/com/candra/projectcapstone/activity/register/RegisterActivity.kt b/app/src/main/java/com/candra/projectcapstone/activity/register/RegisterActivity.kt deleted file mode 100644 index 34861d4..0000000 --- a/app/src/main/java/com/candra/projectcapstone/activity/register/RegisterActivity.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.candra.projectcapstone.activity.register - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.candra.projectcapstone.databinding.ActivityRegisterBinding -import com.candra.projectcapstone.helper.Helper - -class RegisterActivity: AppCompatActivity() -{ - private lateinit var binding: ActivityRegisterBinding - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityRegisterBinding.inflate(layoutInflater) - setContentView(binding.root) - binding.apply { - textviewExistAcount.setOnClickListener { - Helper.toNavigateLoginActivity(this@RegisterActivity) - finish() - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/activity/splash/SplashScreen.kt b/app/src/main/java/com/candra/projectcapstone/activity/splash/SplashScreen.kt index ec6a89e..b5b5edf 100644 --- a/app/src/main/java/com/candra/projectcapstone/activity/splash/SplashScreen.kt +++ b/app/src/main/java/com/candra/projectcapstone/activity/splash/SplashScreen.kt @@ -8,11 +8,9 @@ import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.candra.projectcapstone.activity.home.MainActivity import com.candra.projectcapstone.activity.onboarding.ViewPagerActivity -import com.candra.projectcapstone.activity.tempt.TemplateLoginAndRegister import com.candra.projectcapstone.databinding.SplashScreenActivityBinding import com.candra.projectcapstone.helper.Animation import com.candra.projectcapstone.helper.LocalShared -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/candra/projectcapstone/activity/tempt/TemplateLoginAndRegister.kt b/app/src/main/java/com/candra/projectcapstone/activity/tempt/TemplateLoginAndRegister.kt deleted file mode 100644 index dd5edb4..0000000 --- a/app/src/main/java/com/candra/projectcapstone/activity/tempt/TemplateLoginAndRegister.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.candra.projectcapstone.activity.tempt - -import android.app.Activity -import android.content.Context -import android.content.Intent -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.candra.projectcapstone.activity.login.LoginActivity -import com.candra.projectcapstone.activity.register.RegisterActivity -import com.candra.projectcapstone.databinding.ActivityTemptBinding -import com.candra.projectcapstone.helper.Animation -import com.candra.projectcapstone.helper.Helper - -class TemplateLoginAndRegister: AppCompatActivity() -{ - private lateinit var binding: ActivityTemptBinding - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityTemptBinding.inflate(layoutInflater) - setContentView(binding.root) - - binding.apply { - Animation.playAnimationTempt(image = logoApp,btnLogin = btnLoginTempt,btnRegister = btnRegisterTempt) - btnLoginTempt.setOnClickListener { - Helper.toNavigateLoginActivity(this@TemplateLoginAndRegister) - finish() - } - btnRegisterTempt.setOnClickListener { - Helper.toNavigateRegisterActivity(this@TemplateLoginAndRegister) - finish() - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/adapter/AdapterForFear.kt b/app/src/main/java/com/candra/projectcapstone/adapter/AdapterForFear.kt new file mode 100644 index 0000000..47b215d --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/adapter/AdapterForFear.kt @@ -0,0 +1,59 @@ +package com.candra.projectcapstone.adapter + +import android.content.Intent +import android.net.Uri +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.AsyncListDiffer +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.RecyclerView +import coil.load +import com.candra.projectcapstone.R +import com.candra.projectcapstone.databinding.ListItemMusicBinding +import com.candra.projectcapstone.helper.Helper +import com.candra.projectcapstone.model.ListMusicModel + +class AdapterForFear(): RecyclerView.Adapter() { + + class FearViewHolder(private val binding: ListItemMusicBinding): RecyclerView.ViewHolder(binding.root) { + fun bind(listMusic: ListMusicModel){ + with(binding){ + titleMusic.text = listMusic.title + descriptionMusic.text = listMusic.url + artistMusic.text = listMusic.artis + Helper.imageScreen(imageLogoMusic,listMusic.image) + containerMusic.setOnClickListener { + itemView.context.startActivity(Intent(Intent.ACTION_VIEW,Uri.parse(listMusic.url))) + } + } + } + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): AdapterForFear.FearViewHolder { + return FearViewHolder(ListItemMusicBinding.inflate(LayoutInflater.from(parent.context),parent,false)) + } + + override fun onBindViewHolder(holder: AdapterForFear.FearViewHolder, position: Int) { + holder.bind(listMusic = differ.currentList[position]) + } + + override fun getItemCount(): Int = differ.currentList.size + + private val differ = AsyncListDiffer(this,object: DiffUtil.ItemCallback(){ + override fun areItemsTheSame(oldItem: ListMusicModel, newItem: ListMusicModel): Boolean { + return oldItem.id == newItem.id + } + + override fun areContentsTheSame(oldItem: ListMusicModel, newItem: ListMusicModel): Boolean { + return oldItem == newItem + } + + }) + + fun addAllDataMusic(listData: List){ + differ.submitList(listData) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/api/ApiInterface.kt b/app/src/main/java/com/candra/projectcapstone/api/ApiInterface.kt new file mode 100644 index 0000000..e61de9b --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/api/ApiInterface.kt @@ -0,0 +1,15 @@ +package com.candra.projectcapstone.api + +import com.candra.projectcapstone.api.data.ResponseAllMusicList +import com.candra.projectcapstone.helper.Constant.CATEGORY +import com.candra.projectcapstone.helper.Constant.ENDPOINT +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Path + +interface ApiInterface{ + @GET(ENDPOINT) + suspend fun getAllMusicList( + @Path(CATEGORY) category: String + ): Response +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/api/data/Data.kt b/app/src/main/java/com/candra/projectcapstone/api/data/Data.kt new file mode 100644 index 0000000..08c2c53 --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/api/data/Data.kt @@ -0,0 +1,19 @@ +package com.candra.projectcapstone.api.data + + +import com.google.gson.annotations.SerializedName + +data class Data( + @SerializedName("Artist") + val artist: String, + @SerializedName("Category") + val category: String, + @SerializedName("Id") + val id: Int, + @SerializedName("Image") + val image: String, + @SerializedName("Link") + val link: String, + @SerializedName("Title") + val title: String +) \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/api/data/ResponseAllMusicList.kt b/app/src/main/java/com/candra/projectcapstone/api/data/ResponseAllMusicList.kt new file mode 100644 index 0000000..eb21c3d --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/api/data/ResponseAllMusicList.kt @@ -0,0 +1,11 @@ +package com.candra.projectcapstone.api.data + + +import com.google.gson.annotations.SerializedName + +data class ResponseAllMusicList( + @SerializedName("data") + val data: List, + @SerializedName("success") + val success: Boolean +) \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/di/InjectModule.kt b/app/src/main/java/com/candra/projectcapstone/di/InjectModule.kt deleted file mode 100644 index 7ed271a..0000000 --- a/app/src/main/java/com/candra/projectcapstone/di/InjectModule.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.candra.projectcapstone.di - - -object InjectModule { - -} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/di/MeyApp.kt b/app/src/main/java/com/candra/projectcapstone/di/MeyApp.kt new file mode 100644 index 0000000..43bbf32 --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/di/MeyApp.kt @@ -0,0 +1,7 @@ +package com.candra.projectcapstone.di + +import android.app.Application +import dagger.hilt.android.HiltAndroidApp + +@HiltAndroidApp +class MeyApp : Application() \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/di/NetworkModule.kt b/app/src/main/java/com/candra/projectcapstone/di/NetworkModule.kt new file mode 100644 index 0000000..52e7818 --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/di/NetworkModule.kt @@ -0,0 +1,54 @@ +package com.candra.projectcapstone.di + +import com.candra.projectcapstone.BuildConfig +import com.candra.projectcapstone.api.ApiInterface +import com.candra.projectcapstone.helper.Constant.BASE_URL +import com.candra.projectcapstone.model.RemoteDataSource +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import javax.inject.Singleton + + +@Module +@InstallIn(SingletonComponent::class) +object NetworkModule { + + @Provides + @Singleton + fun providesOkhttpClient(): OkHttpClient { + val loggingInteceptor = if (BuildConfig.DEBUG){ + HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY) + }else{ + HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.NONE) + } + + return OkHttpClient.Builder() + .addInterceptor(loggingInteceptor) + .build() + } + + @Provides + @Singleton + fun provideGsonConverterFactory(): GsonConverterFactory = GsonConverterFactory.create() + + @Provides + @Singleton + fun providesRetrofitInstance( + okHttpClient: OkHttpClient, + gsonConverterFactory: GsonConverterFactory + ): Retrofit = Retrofit.Builder().baseUrl(BASE_URL).client(okHttpClient).addConverterFactory(gsonConverterFactory).build() + + @Provides + @Singleton + fun providesApiService(retrofit: Retrofit): ApiInterface = retrofit.create(ApiInterface::class.java) + + @Provides + @Singleton + fun providesRemoteDataSource(service: ApiInterface): RemoteDataSource = RemoteDataSource(service) +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/fragment/HomeFragment.kt b/app/src/main/java/com/candra/projectcapstone/fragment/HomeFragment.kt new file mode 100644 index 0000000..dbda752 --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/fragment/HomeFragment.kt @@ -0,0 +1,218 @@ +package com.candra.projectcapstone.fragment + +import android.annotation.SuppressLint +import android.app.Activity.RESULT_OK +import android.content.ActivityNotFoundException +import android.content.Intent +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.net.Uri +import android.os.Bundle +import android.provider.MediaStore +import android.provider.Settings +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AlertDialog +import androidx.core.content.ContextCompat +import androidx.core.content.FileProvider +import androidx.fragment.app.Fragment +import com.candra.projectcapstone.R +import com.candra.projectcapstone.activity.home.ListDetailScan +import com.candra.projectcapstone.databinding.FragmentHomeBinding +import com.candra.projectcapstone.helper.CameraUtils.createCustomTemptFile +import com.candra.projectcapstone.helper.Constant +import com.candra.projectcapstone.helper.Helper.makeToast +import com.candra.projectcapstone.ml.ModelFerLarasMetadata +import com.google.android.material.bottomnavigation.BottomNavigationView +import com.karumi.dexter.Dexter +import com.karumi.dexter.PermissionToken +import com.karumi.dexter.listener.PermissionDeniedResponse +import com.karumi.dexter.listener.PermissionGrantedResponse +import com.karumi.dexter.listener.PermissionRequest +import com.karumi.dexter.listener.single.PermissionListener +import org.tensorflow.lite.DataType +import org.tensorflow.lite.support.image.ImageProcessor +import org.tensorflow.lite.support.image.TensorImage +import org.tensorflow.lite.support.image.ops.ResizeOp +import org.tensorflow.lite.support.image.ops.TransformToGrayscaleOp +import org.tensorflow.lite.support.tensorbuffer.TensorBuffer +import java.io.File + +class HomeFragment: Fragment() +{ + private var _binding: FragmentHomeBinding? = null + + private val binding get() = _binding!! + private lateinit var currentPhotoPath: String + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentHomeBinding.inflate(inflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setBackgroundToCardView() + setActionComponentClick() + } + + private fun setBackgroundToCardView(){ + binding.apply { + cardviewContainerFace.background = + ContextCompat.getDrawable(requireActivity(), R.drawable.background_image_scan) + containerBookmark.background = + ContextCompat.getDrawable(requireActivity(), R.drawable.bookmark) + containerNotification.background = + ContextCompat.getDrawable(requireActivity(), R.drawable.notif) + } + } + + private fun setActionComponentClick(){ + binding.apply { + btnAllMusic.setOnClickListener { + val bottomNavigation = + requireActivity().findViewById(R.id.bottom_navigation) + bottomNavigation.selectedItemId = R.id.music + } + cardviewContainerFace.setOnClickListener { + requestPermissionCamera() + } + containerBookmark.setOnClickListener { + makeToast(requireActivity()) + } + containerNotification.setOnClickListener { + makeToast(requireActivity()) + } + } + } + + @SuppressLint("QueryPermissionsNeeded") + private fun setCamera() { + val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) + intent.resolveActivity(requireActivity().packageManager) + + createCustomTemptFile(requireActivity().application).also { + val photoUri: Uri = FileProvider.getUriForFile( + requireActivity(), + "com.candra.projectcapstone", + it + ) + currentPhotoPath = it.absolutePath + intent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri) + launcherIntentCamera.launch(intent) + } + } + + + private val launcherIntentCamera = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ){ + if (it.resultCode == RESULT_OK){ + val myFile = File(currentPhotoPath) + + val result = BitmapFactory.decodeFile(myFile.path) + + setTensorFlow(result,myFile) + + } + } + + private val tfImageProccessor by lazy { + ImageProcessor.Builder() + .add(ResizeOp(48,48, ResizeOp.ResizeMethod.NEAREST_NEIGHBOR)) + .add(TransformToGrayscaleOp()) + .build() + } + + private var tfImage = TensorImage(DataType.FLOAT32) + + private fun setTensorFlow(bitmap: Bitmap, fileScanResult: File){ + val model = ModelFerLarasMetadata.newInstance(requireActivity()) + val byteBuffer = TensorBuffer.createFixedSize(intArrayOf(1,48,48,1), DataType.FLOAT32) + val newBitmap = bitmap.copy(Bitmap.Config.ARGB_8888,true) + + tfImage.load(newBitmap) + tfImage = tfImageProccessor.process(tfImage) + byteBuffer.loadBuffer(tfImage.buffer) + + val outputs = model.process(byteBuffer) + + val highProbability = outputs.probabilityAsCategoryList.apply { + sortByDescending { it.score } + } + val resultScanFace = highProbability[0].label + + sendDataToResultActivity(fileScanResult,resultScanFace) + } + + private fun sendDataToResultActivity(bitmap: File, resultScanFace: String){ + Intent(requireActivity(), ListDetailScan::class.java).apply { + putExtra(Constant.PICTURE,bitmap) + putExtra(Constant.RESULT_SCAN_FACE,resultScanFace) + }.also { startActivity(it) } + } + + private fun requestPermissionCamera(){ + Dexter.withContext(requireActivity()) + .withPermission( + android.Manifest.permission.CAMERA + ).withListener(listenerDexter).onSameThread().check() + } + + private val listenerDexter = object: PermissionListener{ + override fun onPermissionGranted(p0: PermissionGrantedResponse?) { + setCamera() + } + + override fun onPermissionDenied(p0: PermissionDeniedResponse?) { + showDialogPermissionDenied() + } + + override fun onPermissionRationaleShouldBeShown( + p0: PermissionRequest?, + p1: PermissionToken? + ) { + showDialogPermissionDenied() + } + } + + private fun showDialogPermissionDenied() { + AlertDialog.Builder(requireActivity()) + .setMessage("Aplikasi ini membutuhkan fitur perizinan camera anda" + + "Jika fitur ini tidak diaktifkan. Anda tidak bisa menggunakan fitur ini.." + + "Silahkan pergi ke Setting Anda") + .setTitle("Peringatan") + .setIcon(R.drawable.logo_icon) + .setPositiveButton("Pergi ke setting"){_,_ -> + try { + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package",requireActivity().packageName,null) + }.also { requireActivity().startActivity(it) } + }catch (e: ActivityNotFoundException){ + e.printStackTrace() + Log.d(TAG, "showDialogPermissionDenied: ${e.message.toString()}") + } + } + .setNegativeButton("Cancel"){dialog,_ -> + dialog.dismiss() + }.show() + } + + override fun onDestroy() { + super.onDestroy() + _binding = null + } + + companion object{ + const val TAG = "Home Fragment" + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/fragment/MusicFragment.kt b/app/src/main/java/com/candra/projectcapstone/fragment/MusicFragment.kt new file mode 100644 index 0000000..df8939c --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/fragment/MusicFragment.kt @@ -0,0 +1,147 @@ +package com.candra.projectcapstone.fragment + +import android.annotation.SuppressLint +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import com.candra.projectcapstone.R +import com.candra.projectcapstone.adapter.AdapterForFear +import com.candra.projectcapstone.databinding.FragmentMusicBinding +import com.candra.projectcapstone.helper.Constant +import com.candra.projectcapstone.helper.Helper.makeToast +import com.candra.projectcapstone.viewmodel.ListMusicViewModel +import dagger.hilt.android.AndroidEntryPoint + +@SuppressLint("SetTextI18n") +@AndroidEntryPoint +class MusicFragment: Fragment() { + + private var _binding: FragmentMusicBinding? = null + private val binding get() = _binding!! + private lateinit var listViewModel: ListMusicViewModel + private val adapterMain by lazy { AdapterForFear() } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentMusicBinding.inflate(inflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + listViewModel = ViewModelProvider(this)[ListMusicViewModel::class.java] + setActionComponentClick() + setBackgroundCardView() + setObserverData() + setAdapterToMusicFragment() + setTextChip() + } + + private fun setAdapterToMusicFragment(){ + binding.listMusic.apply { + layoutManager = LinearLayoutManager(requireActivity()) + adapter = adapterMain + } + } + + private fun setBackgroundCardView(){ + binding.apply { + containerBookmark.background = ContextCompat.getDrawable(requireActivity(), R.drawable.bookmark) + containerNotification.background = ContextCompat.getDrawable(requireActivity(),R.drawable.notif) + } + } + + private fun setTextChip(){ + binding.apply { + chipAngry.text = Constant.ANGRY + chipHappy.text = Constant.HAPPY + chipNetral.text = Constant.NEUTRAL + chipSad.text = Constant.SAD + chipScarry.text = Constant.FEAR + chipSuprise.text = Constant.SURPRISE + chipDisgust.text = Constant.DISGUST + } + + } + + private fun setActionComponentClick(){ + binding.apply { + containerBookmark.setOnClickListener { makeToast(requireActivity()) } + containerNotification.setOnClickListener { makeToast(requireActivity()) } + setDefaultListMusic() + chipAngry.setOnClickListener { + setChipAndTextView(Constant.ANGRY) + } + chipHappy.setOnClickListener { + setChipAndTextView(Constant.HAPPY) + } + chipNetral.setOnClickListener { + setChipAndTextView(Constant.NEUTRAL) + } + chipSad.setOnClickListener { + setChipAndTextView(Constant.SAD) + } + chipScarry.setOnClickListener { + setChipAndTextView(Constant.FEAR) + } + chipSuprise.setOnClickListener { + setChipAndTextView(Constant.SURPRISE) + } + chipDisgust.setOnClickListener { + setChipAndTextView(Constant.DISGUST) + } + + } + } + + private fun setChipAndTextView(category: String){ + listViewModel.getAllMusicList(category) + binding.textYourMood.text = "list of songs based on your $category mood " + } + + private fun setObserverData(){ + listViewModel.listMusicData.observe(viewLifecycleOwner){ + adapterMain.addAllDataMusic(it) + } + + listViewModel.loading.observe(viewLifecycleOwner){ + showShimmerEffect(it) + } + } + + private fun setDefaultListMusic(){ + listViewModel.getAllMusicList(Constant.HAPPY) + binding.apply { + chipHappy.isChecked = true + chipHappy.text = Constant.HAPPY + textYourMood.text = "list of songs based on your ${Constant.HAPPY} mood " + } + } + + private fun showShimmerEffect(show: Boolean){ + binding.apply { + if (show){ + shimmerEffect.startShimmer() + shimmerEffect.visibility = View.VISIBLE + listMusic.visibility = View.GONE + }else{ + shimmerEffect.hideShimmer() + shimmerEffect.visibility = View.GONE + listMusic.visibility = View.VISIBLE + } + } + } + + override fun onDestroy() { + super.onDestroy() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/helper/Animation.kt b/app/src/main/java/com/candra/projectcapstone/helper/Animation.kt index 76d91a8..a2202e2 100644 --- a/app/src/main/java/com/candra/projectcapstone/helper/Animation.kt +++ b/app/src/main/java/com/candra/projectcapstone/helper/Animation.kt @@ -30,5 +30,4 @@ object Animation { start() } } - } \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/helper/CameraUtils.kt b/app/src/main/java/com/candra/projectcapstone/helper/CameraUtils.kt new file mode 100644 index 0000000..a3a311c --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/helper/CameraUtils.kt @@ -0,0 +1,24 @@ +package com.candra.projectcapstone.helper + +import android.annotation.SuppressLint +import android.content.Context +import android.os.Environment +import java.io.File +import java.text.SimpleDateFormat +import java.util.* + +object CameraUtils { + + private const val FILENAME_FORMAT = "dd-MM-yyyy" + + @SuppressLint("ConstantLocale") + private val timeStampt: String = SimpleDateFormat( + FILENAME_FORMAT, + Locale.getDefault() + ).format(System.currentTimeMillis()) + + fun createCustomTemptFile(context: Context): File { + val storage: File? = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) + return File.createTempFile(timeStampt,".jpg",storage) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/helper/Constant.kt b/app/src/main/java/com/candra/projectcapstone/helper/Constant.kt index c0c5a1d..5ee022e 100644 --- a/app/src/main/java/com/candra/projectcapstone/helper/Constant.kt +++ b/app/src/main/java/com/candra/projectcapstone/helper/Constant.kt @@ -4,5 +4,18 @@ import androidx.datastore.preferences.core.booleanPreferencesKey object Constant { - val isCheckedOnBoarding = booleanPreferencesKey("isCheckedOnBoarding") + val isCheckedOnBoarding = booleanPreferencesKey("isCheckedOnBoarding") + const val PICTURE = "picture" + const val RESULT_SCAN_FACE = "result_scan_face" + const val BASE_URL = "https://modular-edge-352015.et.r.appspot.com/" + const val ENDPOINT = "tampil/{Category}" + const val CATEGORY = "Category" + const val TAG = "RemtoeDataSource" + const val SAD = "Sad" + const val HAPPY = "Happiness" + const val DISGUST = "Disgust" + const val ANGRY = "Angry" + const val NEUTRAL = "Neutral" + const val FEAR = "Fear" + const val SURPRISE = "Surprise" } \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/helper/Hekper.kt b/app/src/main/java/com/candra/projectcapstone/helper/Hekper.kt index 7003017..9684526 100644 --- a/app/src/main/java/com/candra/projectcapstone/helper/Hekper.kt +++ b/app/src/main/java/com/candra/projectcapstone/helper/Hekper.kt @@ -3,48 +3,50 @@ package com.candra.projectcapstone.helper import android.content.Context import android.content.Intent import android.widget.ImageView +import android.widget.Toast +import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity +import androidx.fragment.app.FragmentManager import androidx.lifecycle.LifecycleCoroutineScope import coil.load import com.candra.projectcapstone.R -import com.candra.projectcapstone.activity.login.LoginActivity -import com.candra.projectcapstone.activity.register.RegisterActivity -import com.candra.projectcapstone.activity.tempt.TemplateLoginAndRegister +import com.candra.projectcapstone.activity.home.MainActivity import kotlinx.coroutines.launch object Helper { - const val IMAGE_SCREEN_ONE = "https://raw.githubusercontent.com/MEY-Mental-Education-Yes/The-Logo-MEY/main/onBoarding_1.png" - const val IMAGE_SCREEN_TWO = "https://raw.githubusercontent.com/MEY-Mental-Education-Yes/The-Logo-MEY/main/OnBoarding_2.png" - const val IMAGE_SCREEN_THREE = "https://raw.githubusercontent.com/MEY-Mental-Education-Yes/The-Logo-MEY/main/onBoarding_3.png" + const val IMAGE_SCREEN_ONE = + "https://raw.githubusercontent.com/MEY-Mental-Education-Yes/The-Logo-MEY/main/onBoarding_1.png" + const val IMAGE_SCREEN_TWO = + "https://raw.githubusercontent.com/MEY-Mental-Education-Yes/The-Logo-MEY/main/OnBoarding_2.png" - - fun imageScreen(image: ImageView,url: String){ - image.load(url){ + fun imageScreen(image: ImageView, url: String) { + image.load(url) { crossfade(true) crossfade(600) error(R.drawable.ic_baseline_broken_image_24) } } - fun toScreenHome(fragmentActivity: FragmentActivity){ - fragmentActivity.startActivity(Intent(fragmentActivity,TemplateLoginAndRegister::class.java)) + fun toHomeScreen(fragmentActivity: FragmentActivity){ + fragmentActivity.startActivity(Intent(fragmentActivity,MainActivity::class.java)) fragmentActivity.finish() } - - fun setCheckedData(lifecycle: LifecycleCoroutineScope,context: Context){ + + fun setCheckedData(lifecycle: LifecycleCoroutineScope, context: Context) { lifecycle.launch { LocalShared.setCheckedLocalOnBoarding(context) } } - fun toNavigateLoginActivity(context: Context){ - context.startActivity(Intent(context,LoginActivity::class.java)) + fun loadFragment(fragment: Fragment, fragmentManager: FragmentManager) { + fragmentManager.beginTransaction().replace(R.id.parentContainer, fragment).commit() } - fun toNavigateRegisterActivity(context: Context){ - context.startActivity(Intent(context,RegisterActivity::class.java)) + fun makeToast(context: Context){ + Toast.makeText(context,context.getString(R.string.tahap_developer),Toast.LENGTH_SHORT).show() } -} \ No newline at end of file + +} diff --git a/app/src/main/java/com/candra/projectcapstone/helper/LocalShared.kt b/app/src/main/java/com/candra/projectcapstone/helper/LocalShared.kt index 0977f2f..0761521 100644 --- a/app/src/main/java/com/candra/projectcapstone/helper/LocalShared.kt +++ b/app/src/main/java/com/candra/projectcapstone/helper/LocalShared.kt @@ -13,7 +13,6 @@ object LocalShared { private val Context.dataStore: DataStore by preferencesDataStore(name = "localstore") - fun getCheckedLocalOnBoarding(context: Context): Flow = context.dataStore.data.map { preferences -> preferences[isCheckedOnBoarding]?: false } diff --git a/app/src/main/java/com/candra/projectcapstone/helper/State.kt b/app/src/main/java/com/candra/projectcapstone/helper/State.kt new file mode 100644 index 0000000..9ea7212 --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/helper/State.kt @@ -0,0 +1,15 @@ +package com.candra.projectcapstone.helper + +import com.candra.projectcapstone.model.ListMusicModel + +sealed class State{ + class Loading: State() + data class Success(val data: T): State() + data class Failed(val message: String): State() + + companion object{ + fun loading() = Loading() + fun success(data: T) = Success(data) + fun failed(message: String) = Failed(message) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/model/ListMusicModel.kt b/app/src/main/java/com/candra/projectcapstone/model/ListMusicModel.kt new file mode 100644 index 0000000..b9b4e42 --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/model/ListMusicModel.kt @@ -0,0 +1,30 @@ +package com.candra.projectcapstone.model + +import android.os.Parcelable +import com.candra.projectcapstone.api.data.Data +import kotlinx.parcelize.Parcelize + +@Parcelize +data class ListMusicModel( + val id: Int, + val title: String, + val artis: String, + val url: String, + val image: String +): Parcelable + +fun List.toGenerateListMusic(): MutableList { + val listMusic = mutableListOf() + this.forEach { listMusic.add(it.toListMusic()) } + return listMusic +} + +fun Data.toListMusic(): ListMusicModel{ + return ListMusicModel( + id = this.id?: 0, + title = this.title?: "", + artis = this.artist ?: "", + image = this.image ?: "", + url = this.link ?: "", + ) +} diff --git a/app/src/main/java/com/candra/projectcapstone/model/RemoteDataSource.kt b/app/src/main/java/com/candra/projectcapstone/model/RemoteDataSource.kt new file mode 100644 index 0000000..b4c9f15 --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/model/RemoteDataSource.kt @@ -0,0 +1,31 @@ +package com.candra.projectcapstone.model + +import android.util.Log +import com.candra.projectcapstone.api.ApiInterface +import com.candra.projectcapstone.helper.Constant.TAG +import com.candra.projectcapstone.helper.State +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn +import java.lang.Exception +import javax.inject.Inject + +class RemoteDataSource @Inject constructor( + private val apiService: ApiInterface +) { + suspend fun getAllListMusic(category: String) = flow>> { + emit(State.loading()) + val responseMusicList = apiService.getAllMusicList(category) + responseMusicList.let { + if (it.isSuccessful && it.body() != null){ + emit(State.success(it.body()?.data?.toGenerateListMusic()?: listOf())) + }else{ + emit(State.failed(it.message()?: "")) + } + } + }.catch { + Log.d(TAG, "getAllListMusic: failed = ${it.message}") + emit(State.failed(it.message.toString())) + }.flowOn(Dispatchers.IO) +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/repo/ListMusicRepository.kt b/app/src/main/java/com/candra/projectcapstone/repo/ListMusicRepository.kt new file mode 100644 index 0000000..7c27a5e --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/repo/ListMusicRepository.kt @@ -0,0 +1,16 @@ +package com.candra.projectcapstone.repo + +import com.candra.projectcapstone.helper.State +import com.candra.projectcapstone.model.ListMusicModel +import com.candra.projectcapstone.model.RemoteDataSource +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class ListMusicRepository @Inject constructor( + private val remoteDataSource: RemoteDataSource +): ListMusicRepositoryImpl { + override suspend fun getAllMusicList(category: String): Flow>> { + return remoteDataSource.getAllListMusic(category) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/repo/ListMusicRepositoryImpl.kt b/app/src/main/java/com/candra/projectcapstone/repo/ListMusicRepositoryImpl.kt new file mode 100644 index 0000000..2859100 --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/repo/ListMusicRepositoryImpl.kt @@ -0,0 +1,9 @@ +package com.candra.projectcapstone.repo + +import com.candra.projectcapstone.helper.State +import com.candra.projectcapstone.model.ListMusicModel +import kotlinx.coroutines.flow.Flow + +interface ListMusicRepositoryImpl { + suspend fun getAllMusicList(category: String): Flow>> +} \ No newline at end of file diff --git a/app/src/main/java/com/candra/projectcapstone/viewmodel/ListMusicViewModel.kt b/app/src/main/java/com/candra/projectcapstone/viewmodel/ListMusicViewModel.kt new file mode 100644 index 0000000..da4626c --- /dev/null +++ b/app/src/main/java/com/candra/projectcapstone/viewmodel/ListMusicViewModel.kt @@ -0,0 +1,40 @@ +package com.candra.projectcapstone.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.candra.projectcapstone.helper.State +import com.candra.projectcapstone.model.ListMusicModel +import com.candra.projectcapstone.repo.ListMusicRepository +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class ListMusicViewModel @Inject constructor( + private val repository: ListMusicRepository +): ViewModel() { + + private var _isLoading = MutableLiveData() + val loading get() = _isLoading + + private var _listMusicData = MutableLiveData>() + val listMusicData get() = _listMusicData + + fun getAllMusicList(category: String) = viewModelScope.launch { + repository.getAllMusicList(category).collect { + when(it){ + is State.Loading -> { _isLoading.value = true } + is State.Success -> { + _isLoading.value = false + it.data.let { listMusic -> _listMusicData.value = listMusic } + } + is State.Failed -> { + _isLoading.value = false + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/res/color/chip_background.xml b/app/src/main/res/color/chip_background.xml new file mode 100644 index 0000000..2bdd160 --- /dev/null +++ b/app/src/main/res/color/chip_background.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/chip_text_color.xml b/app/src/main/res/color/chip_text_color.xml new file mode 100644 index 0000000..0643cc5 --- /dev/null +++ b/app/src/main/res/color/chip_text_color.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/color_background_selected_cardview.xml b/app/src/main/res/color/color_background_selected_cardview.xml new file mode 100644 index 0000000..13840c0 --- /dev/null +++ b/app/src/main/res/color/color_background_selected_cardview.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/item_color.xml b/app/src/main/res/color/item_color.xml new file mode 100644 index 0000000..577686f --- /dev/null +++ b/app/src/main/res/color/item_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/bookmark.png b/app/src/main/res/drawable-v24/bookmark.png new file mode 100644 index 0000000..1af2299 Binary files /dev/null and b/app/src/main/res/drawable-v24/bookmark.png differ diff --git a/app/src/main/res/drawable-v24/email.png b/app/src/main/res/drawable-v24/email.png deleted file mode 100644 index f97a99e..0000000 Binary files a/app/src/main/res/drawable-v24/email.png and /dev/null differ diff --git a/app/src/main/res/drawable-v24/lock.png b/app/src/main/res/drawable-v24/lock.png deleted file mode 100644 index 8961b96..0000000 Binary files a/app/src/main/res/drawable-v24/lock.png and /dev/null differ diff --git a/app/src/main/res/drawable-v24/notif.png b/app/src/main/res/drawable-v24/notif.png new file mode 100644 index 0000000..c593931 Binary files /dev/null and b/app/src/main/res/drawable-v24/notif.png differ diff --git a/app/src/main/res/drawable-v24/user.png b/app/src/main/res/drawable-v24/user.png deleted file mode 100644 index 1a014ed..0000000 Binary files a/app/src/main/res/drawable-v24/user.png and /dev/null differ diff --git a/app/src/main/res/drawable/background_bottom_navigation.xml b/app/src/main/res/drawable/background_bottom_navigation.xml new file mode 100644 index 0000000..7c8a47d --- /dev/null +++ b/app/src/main/res/drawable/background_bottom_navigation.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_cardview.xml b/app/src/main/res/drawable/background_cardview.xml new file mode 100644 index 0000000..d1bef3b --- /dev/null +++ b/app/src/main/res/drawable/background_cardview.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_home.xml b/app/src/main/res/drawable/background_home.xml new file mode 100644 index 0000000..f37edf2 --- /dev/null +++ b/app/src/main/res/drawable/background_home.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_image_scan.xml b/app/src/main/res/drawable/background_image_scan.xml new file mode 100644 index 0000000..ef4c8c3 --- /dev/null +++ b/app/src/main/res/drawable/background_image_scan.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/camera_back.png b/app/src/main/res/drawable/camera_back.png new file mode 100644 index 0000000..7d5b069 Binary files /dev/null and b/app/src/main/res/drawable/camera_back.png differ diff --git a/app/src/main/res/drawable/face_recognition.png b/app/src/main/res/drawable/face_recognition.png new file mode 100644 index 0000000..f22357e Binary files /dev/null and b/app/src/main/res/drawable/face_recognition.png differ diff --git a/app/src/main/res/drawable/ic_baseline_home_24.xml b/app/src/main/res/drawable/ic_baseline_home_24.xml new file mode 100644 index 0000000..f7d55f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_home_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_music_note_24.xml b/app/src/main/res/drawable/ic_baseline_music_note_24.xml new file mode 100644 index 0000000..6c4e3c0 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_music_note_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9..0000000 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/turn_back.png b/app/src/main/res/drawable/turn_back.png new file mode 100644 index 0000000..798868d Binary files /dev/null and b/app/src/main/res/drawable/turn_back.png differ diff --git a/app/src/main/res/drawable/vector.png b/app/src/main/res/drawable/vector.png deleted file mode 100644 index b62f2cc..0000000 Binary files a/app/src/main/res/drawable/vector.png and /dev/null differ diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml deleted file mode 100644 index 9174be9..0000000 --- a/app/src/main/res/layout/activity_login.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index a817ec8..1e1d043 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,18 +1,34 @@ - - + + + + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:itemTextColor="@color/item_color" + app:itemIconTint="@color/item_color" + app:layout_constraintBottom_toBottomOf="parent"/> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_register.xml b/app/src/main/res/layout/activity_register.xml deleted file mode 100644 index 876d945..0000000 --- a/app/src/main/res/layout/activity_register.xml +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_tempt.xml b/app/src/main/res/layout/activity_tempt.xml deleted file mode 100644 index 514024a..0000000 --- a/app/src/main/res/layout/activity_tempt.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..3505197 --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_music.xml b/app/src/main/res/layout/fragment_music.xml new file mode 100644 index 0000000..0ae9207 --- /dev/null +++ b/app/src/main/res/layout/fragment_music.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_screen_one.xml b/app/src/main/res/layout/fragment_screen_one.xml index 3fe88e0..4038b8f 100644 --- a/app/src/main/res/layout/fragment_screen_one.xml +++ b/app/src/main/res/layout/fragment_screen_one.xml @@ -1,25 +1,10 @@ - - - - - - + /> - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_screen_two.xml b/app/src/main/res/layout/fragment_screen_two.xml index 9d73017..4e3a9b3 100644 --- a/app/src/main/res/layout/fragment_screen_two.xml +++ b/app/src/main/res/layout/fragment_screen_two.xml @@ -5,22 +5,6 @@ android:background="@color/splash_screen_color" android:layout_height="match_parent"> - - - - + /> + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/list_item_music.xml b/app/src/main/res/layout/list_item_music.xml new file mode 100644 index 0000000..e6434be --- /dev/null +++ b/app/src/main/res/layout/list_item_music.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/result_activity.xml b/app/src/main/res/layout/result_activity.xml new file mode 100644 index 0000000..c754fe1 --- /dev/null +++ b/app/src/main/res/layout/result_activity.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/splash_screen_activity.xml b/app/src/main/res/layout/splash_screen_activity.xml index f8a7b4d..2e809bd 100644 --- a/app/src/main/res/layout/splash_screen_activity.xml +++ b/app/src/main/res/layout/splash_screen_activity.xml @@ -28,6 +28,7 @@ android:layout_marginBottom="244dp" android:alpha="0" android:text="@string/app_name" + android:textColor="@android:color/black" android:id="@+id/title" android:textAllCaps="true" android:textSize="36sp" diff --git a/app/src/main/res/menu/menu.xml b/app/src/main/res/menu/menu.xml new file mode 100644 index 0000000..fddb01c --- /dev/null +++ b/app/src/main/res/menu/menu.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index eca70cf..036d09b 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index eca70cf..036d09b 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..50695b8 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp deleted file mode 100644 index c209e78..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..3ee4a06 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..7de8764 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index b2dfe3d..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..0c346fa Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp deleted file mode 100644 index 4f0f1d6..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..19533dc Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..4f368ac Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp deleted file mode 100644 index 62b611d..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..fbb47e3 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp deleted file mode 100644 index 948a307..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..b0101ad Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..68f84db Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 1b9a695..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..725a601 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp deleted file mode 100644 index 28d4b77..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..c30b1f5 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..a36959a Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9287f50..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..23de7e4 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp deleted file mode 100644 index aa7d642..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..880fd51 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..a87552c Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9126ae3..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 8ae6d81..f0d8a1a 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -12,5 +12,9 @@ ?attr/colorPrimaryVariant + + true + @android:transition/explode + @android:transition/explode \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index cf1f274..ceff63e 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -9,4 +9,7 @@ #FFFFFFFF #82B3C9 #DBDAF5 + #F0F7F8 + #F3F3F3 + #dddddd \ No newline at end of file diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..6d71638 --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #F0F7F8 + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4085d5f..e917307 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,23 +1,26 @@ MEY Logo App - Kenali Suasana Hatimu dengan Mudah - Lewati - Lanjut - Aplikasi MEY membantu mengenali suasana hatimu melalui Pengenalan Ekpresi Wajah sehingga kamu dapat sehingga kamu dapat mengatasi suasuan hatimu dengan mudah dan cepat bersama MEY - gambar1 - Kenali Playlistmu sesuai Moodmu setiap hari - Aplikasi MEY membantu untuk memutarkan lagu sesuai dengan ekspresi wajah yang anda scanning dengan mudah bersama MEY - Buatlah Harimu Menjadi Lebih Produktif dengan mencatat Jadwal - Aplikasi MEY membantumu dalam mencatat Jadwal, membuat Reminder agar harimu lebih Produktif - Selesai - Login - Buat Akun Baru - Register - Nama Lengkap - Email - Password - Sudah Punya Akun? Yuk Login - Lupa password - Belum Punya Akun ? Yuk Register + Recognize Your Mood Easily + Skip + Next + The MEY application helps recognize your mood through Facial Expression Recognition so you can so that you can overcome your mood easily and quickly with MEY + Get to know your playlist according to your mood every day + MEY application helps to play songs according to facial expressions that you scan easily with MEY + Finish + Home + List Music + How your mood? + Click Music + Face Scan Results + Image Music + Deskripsi Music + Title Music + Scan Your Face + This feature is still under development + Failed to take pictures + Failed to display camera + Artist + gambar + welcome \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index c36efcc..f44a9ea 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -12,5 +12,13 @@ ?attr/colorPrimaryVariant + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/file_path.xml b/app/src/main/res/xml/file_path.xml new file mode 100644 index 0000000..ed349d1 --- /dev/null +++ b/app/src/main/res/xml/file_path.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index cd0519b..3c7a8bd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,4 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true