Last active
July 25, 2020 14:04
-
-
Save Lukmannudin/4bd698d722c4de61cb6bc72fafca0b57 to your computer and use it in GitHub Desktop.
Source Code Aplikasi Sleepy Platform Android Sesudah Reengineering
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.remoteapi | |
| import id.diamondsleep.data.mapper.BaseRemote | |
| import id.diamondsleep.data.source.dataarticle.articleremote.ArticleRemote | |
| import retrofit2.Response | |
| import retrofit2.http.GET | |
| import retrofit2.http.Path | |
| interface ArticleApi { | |
| @GET("articles/{page}") | |
| suspend fun getArticles(@Path("page") page: Int): Response<BaseRemote<List<ArticleRemote>>> | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.source.dataarticle.articlelocal | |
| import androidx.room.* | |
| @Dao | |
| interface ArticleDao { | |
| @Query("SELECT * FROM articles") | |
| suspend fun getArticles(): List<ArticleLocal> | |
| @Query("SELECT * FROM articles WHERE idArticle =:idArticle") | |
| suspend fun getArticle(idArticle: Int): ArticleLocal | |
| @Query("DELETE FROM articles") | |
| suspend fun clearArticles() | |
| @Insert(onConflict = OnConflictStrategy.REPLACE) | |
| fun insertArticle(article: List<ArticleLocal>) | |
| @Delete | |
| fun delete(article: ArticleLocal) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.source | |
| import id.diamondsleep.model.Article | |
| import id.diamondsleep.model.Result | |
| interface ArticleDataSource { | |
| suspend fun getArticle(idArticle: Int): Result<Article> | |
| suspend fun getArticles(page: Int): Result<List<Article>> | |
| suspend fun saveArticles(articles: List<Article>) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.source.dataarticle.articlelocal | |
| import androidx.room.Entity | |
| import androidx.room.PrimaryKey | |
| @Entity(tableName = "articles") | |
| data class ArticleLocal( | |
| @PrimaryKey | |
| val idArticle: Int, | |
| val title: String, | |
| val imageUrl: String, | |
| val content: String, | |
| val source: String, | |
| val date: String, | |
| val author: String | |
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.source.dataarticle.articlelocal | |
| import id.diamondsleep.data.mapper.articlemapper.ArticleMapper | |
| import id.diamondsleep.data.source.ArticleDataSource | |
| import id.diamondsleep.model.Article | |
| import id.diamondsleep.model.Result | |
| class ArticleLocalDataSource( | |
| private val articleDao: ArticleDao | |
| ) : ArticleDataSource { | |
| override suspend fun getArticle(idArticle: Int): Result<Article> { | |
| return try { | |
| Result.Success(ArticleMapper.articleLocalToArticle(articleDao.getArticle(idArticle))) | |
| } catch (e: Exception) { | |
| e.printStackTrace() | |
| Result.Error(Exception(e.localizedMessage)) | |
| } | |
| } | |
| override suspend fun getArticles(page: Int): Result<List<Article>> { | |
| return try { | |
| Result.Success(ArticleMapper.articlesLocalToArticles(articleDao.getArticles())) | |
| } catch (e: Exception) { | |
| e.printStackTrace() | |
| Result.Error(Exception(e.localizedMessage)) | |
| } | |
| } | |
| override suspend fun saveArticles(articles: List<Article>) { | |
| articleDao.clearArticles() | |
| articleDao.insertArticle(ArticleMapper.articlesToLocals(articles)) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.mapper.articlemapper | |
| import id.diamondsleep.data.mapper.Mapper | |
| import id.diamondsleep.data.source.dataarticle.articlelocal.ArticleLocal | |
| import id.diamondsleep.model.Article | |
| class ArticleLocalToArticle : Mapper<ArticleLocal, Article> { | |
| override fun map(input: ArticleLocal): Article { | |
| return Article( | |
| input.idArticle, | |
| input.title, | |
| input.imageUrl, | |
| input.content, | |
| input.source, | |
| input.date, | |
| input.author | |
| ) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.mapper.articlemapper | |
| import id.diamondsleep.data.source.dataarticle.articlelocal.ArticleLocal | |
| import id.diamondsleep.data.source.dataarticle.articleremote.ArticleRemote | |
| import id.diamondsleep.model.Article | |
| object ArticleMapper { | |
| fun articlesRemoteToArticles(articlesRemote: List<ArticleRemote>): List<Article> { | |
| return ArticlesRemoteToArticles(ArticleRemoteToArticle()).map(articlesRemote) | |
| } | |
| fun articleLocalToArticle(articleLocal: ArticleLocal): Article { | |
| return ArticleLocalToArticle().map(articleLocal) | |
| } | |
| fun articlesLocalToArticles(articlesLocal: List<ArticleLocal>): List<Article> { | |
| return ArticlesLocalToArticles(ArticleLocalToArticle()).map(articlesLocal) | |
| } | |
| fun articlesToLocals(articles: List<Article>): List<ArticleLocal> { | |
| return ArticlesToLocal(ArticleToLocal()).map(articles) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.source.dataarticle | |
| import id.diamondsleep.data.source.ArticleDataSource | |
| import id.diamondsleep.model.Article | |
| import id.diamondsleep.model.Result | |
| import kotlinx.coroutines.CoroutineDispatcher | |
| import kotlinx.coroutines.Dispatchers | |
| import kotlinx.coroutines.flow.Flow | |
| import kotlinx.coroutines.flow.flow | |
| import kotlinx.coroutines.withContext | |
| import timber.log.Timber | |
| class ArticleRepository( | |
| private val articleRemoteDataSource: ArticleDataSource, | |
| private val articleLocalDataSource: ArticleDataSource, | |
| private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO | |
| ) : ArticleRepositoryContract { | |
| override suspend fun getArticle(idArticle: Int): Flow<Result<Article>> = flow { | |
| when (val resultLocal = articleLocalDataSource.getArticle(idArticle)) { | |
| is Result.Success -> { | |
| emit(Result.Success(resultLocal.data)) | |
| } | |
| is Result.Error -> { | |
| emit(Result.Error(resultLocal.exception)) | |
| } | |
| } | |
| } | |
| override suspend fun getArticles(page: Int): Flow<Result<List<Article>>> = flow { | |
| when (val resultLocal = articleLocalDataSource.getArticles(page)) { | |
| is Result.Success -> { | |
| emit(Result.Success(resultLocal.data)) | |
| } | |
| is Result.Error -> { | |
| emit(Result.Error(resultLocal.exception)) | |
| } | |
| } | |
| when (val resultRemote = articleRemoteDataSource.getArticles(page)) { | |
| is Result.Success -> { | |
| saveArticles(resultRemote.data) | |
| emit(Result.Success(resultRemote.data)) | |
| } | |
| is Result.Error -> { | |
| emit(Result.Error(resultRemote.exception)) | |
| } | |
| } | |
| } | |
| override suspend fun saveArticles(articles: List<Article>) { | |
| withContext(ioDispatcher) { | |
| articleLocalDataSource.saveArticles(articles) | |
| articleRemoteDataSource.saveArticles(articles) | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.source.dataarticle | |
| import id.diamondsleep.model.Article | |
| import id.diamondsleep.model.Result | |
| import kotlinx.coroutines.flow.Flow | |
| interface ArticleRepositoryContract { | |
| suspend fun getArticle(idArticle: Int): Flow<Result<Article>> | |
| suspend fun getArticles(page: Int): Flow<Result<List<Article>>> | |
| suspend fun saveArticles(articles: List<Article>) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.home.tips | |
| import android.os.Bundle | |
| import android.view.MenuItem | |
| import androidx.appcompat.app.AppCompatActivity | |
| import androidx.core.text.HtmlCompat | |
| import com.bumptech.glide.Glide | |
| import id.diamondsleep.R | |
| import id.diamondsleep.model.Tip | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.utilities.helper.StringToDateConverter | |
| import kotlinx.android.synthetic.main.activity_content_article.* | |
| class DetailTipsActivity : AppCompatActivity() { | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| setContentView(R.layout.activity_content_article) | |
| supportActionBar?.setDisplayHomeAsUpEnabled(true) | |
| supportActionBar?.title = resources.getString(R.string.tips) | |
| val dataIntentTips = intent.getParcelableExtra<Tip>(ConstantValue.DATA_CONTENT) | |
| setView(dataIntentTips) | |
| } | |
| private fun setView(tips: Tip) { | |
| detail_content_title.text = tips.title | |
| detail_content_author.text = tips.author | |
| detail_content_date.text = StringToDateConverter.changeFormatDate(tips.date) | |
| detail_content_text.text = HtmlCompat.fromHtml(tips.content, HtmlCompat.FROM_HTML_MODE_COMPACT) | |
| Glide.with(this).load(tips.imageUrl).into(detail_content_thumbnail) | |
| detail_content_source.text = tips.source | |
| } | |
| override fun onOptionsItemSelected(item: MenuItem?): Boolean { | |
| if (item?.itemId == android.R.id.home) { | |
| super.onBackPressed() | |
| } | |
| return super.onOptionsItemSelected(item) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.utilities.backgroundservice | |
| import android.app.Service | |
| import android.content.Context | |
| import android.content.Intent | |
| import android.net.ConnectivityManager | |
| import android.net.wifi.WifiManager | |
| import android.os.IBinder | |
| import id.diamondsleep.utilities.ConstantValue | |
| import java.lang.reflect.InvocationTargetException | |
| import java.util.* | |
| class InternetService : Service() { | |
| private val twoHours = 60 * 120 | |
| override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { | |
| if (intent!!.getBooleanExtra(ConstantValue.DEACTIVE_SERVICE, false)) { | |
| stopSelf() | |
| } | |
| var increment = 0 | |
| Timer().scheduleAtFixedRate(object : TimerTask() { | |
| override fun run() { | |
| increment++ | |
| if (increment == twoHours) { | |
| increment = 0 | |
| setMobileDataEnabled(this@InternetService, false) | |
| setWifiEnabled(this@InternetService, false) | |
| } | |
| } | |
| }, 0, 1000) | |
| return START_NOT_STICKY | |
| } | |
| @Throws(ClassNotFoundException::class, NoSuchFieldException::class, IllegalAccessException::class, NoSuchMethodException::class, InvocationTargetException::class) | |
| fun setMobileDataEnabled(context: Context, enabled: Boolean) { | |
| val conman = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager | |
| val conmanClass = Class.forName(conman.javaClass.name) | |
| val connectivityManagerField = conmanClass.getDeclaredField("mService") | |
| connectivityManagerField.isAccessible = true | |
| val connectivityManager: Any = connectivityManagerField.get(conman) | |
| val connectivityManagerClass = Class.forName(connectivityManager.javaClass.name) | |
| val setMobileDataEnabledMethod = connectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", java.lang.Boolean.TYPE) | |
| setMobileDataEnabledMethod.isAccessible = true | |
| setMobileDataEnabledMethod.invoke(connectivityManager, enabled) | |
| } | |
| fun setWifiEnabled(context: Context, status: Boolean) { | |
| val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager | |
| wifiManager.isWifiEnabled = status | |
| } | |
| override fun onBind(intent: Intent?): IBinder? { | |
| return null | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.utilities.backgroundservice | |
| import android.app.Service | |
| import android.content.Context | |
| import android.content.Intent | |
| import android.hardware.Sensor | |
| import android.hardware.SensorEvent | |
| import android.hardware.SensorEventListener | |
| import android.hardware.SensorManager | |
| import android.os.IBinder | |
| import id.diamondsleep.R | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.utilities.SleepyNotification | |
| import java.util.* | |
| import kotlin.math.roundToInt | |
| class LightService : Service() { | |
| private lateinit var sensorManager: SensorManager | |
| private lateinit var lightSensor: Sensor | |
| private var lightValue = 0 | |
| private var lightIntensityValueSum = 0 | |
| private val lightIntensityTolerance = 80 | |
| private var timeLimit = 60 * 5 | |
| private var incrementMillisecond = 0 | |
| override fun onCreate() { | |
| super.onCreate() | |
| sensorManager = applicationContext.getSystemService(Context.SENSOR_SERVICE) as SensorManager | |
| lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) | |
| } | |
| override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { | |
| if (intent!!.getBooleanExtra(ConstantValue.DEACTIVE_SERVICE, false)) { | |
| stopSelf() | |
| } | |
| sensorManager.registerListener(lightSensorListener, lightSensor, SensorManager.SENSOR_DELAY_NORMAL) | |
| Timer().scheduleAtFixedRate(object : TimerTask() { | |
| override fun run() { | |
| ++incrementMillisecond | |
| lightIntensityValueSum += lightValue | |
| showNotificationIfLightIntencityDisturbing() | |
| } | |
| }, 0, 1000) | |
| return START_NOT_STICKY | |
| } | |
| private fun showNotificationIfLightIntencityDisturbing() { | |
| if (incrementMillisecond == timeLimit) { | |
| incrementMillisecond = 0 | |
| val meanLightValue = lightIntensityValueSum / timeLimit | |
| if (meanLightValue > lightIntensityTolerance) { | |
| showLightIntencityNotification() | |
| } | |
| } | |
| } | |
| private fun showLightIntencityNotification() { | |
| val notification = SleepyNotification(this@LightService) | |
| notification.apply { | |
| title = "Light Intensity $lightValue lux" | |
| message = getString(R.string.message_for_turnoff_light_disturbing) | |
| showNotification() | |
| } | |
| } | |
| override fun onBind(intent: Intent?): IBinder? { | |
| return null | |
| } | |
| override fun onDestroy() { | |
| super.onDestroy() | |
| sensorManager.unregisterListener(lightSensorListener) | |
| } | |
| private val lightSensorListener = object : SensorEventListener { | |
| override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) { | |
| } | |
| override fun onSensorChanged(event: SensorEvent?) { | |
| lightValue = event!!.values[0].roundToInt() | |
| if (isFirstValueChanged) { | |
| showLightIntencityNotification() | |
| isFirstValueChanged = false | |
| } | |
| } | |
| } | |
| companion object { | |
| var isFirstValueChanged = true | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.login | |
| import android.content.Intent | |
| import android.os.Bundle | |
| import android.view.View | |
| import android.widget.Toast | |
| import androidx.activity.viewModels | |
| import androidx.appcompat.app.AppCompatActivity | |
| import androidx.lifecycle.Observer | |
| import com.google.android.gms.auth.api.signin.GoogleSignIn | |
| import com.google.android.gms.auth.api.signin.GoogleSignInClient | |
| import com.google.android.gms.common.api.ApiException | |
| import id.diamondsleep.MainActivity | |
| import id.diamondsleep.R | |
| import id.diamondsleep.getUserViewModelFactory | |
| import id.diamondsleep.utilities.Preferences | |
| import kotlinx.android.synthetic.main.layout_login.* | |
| class LoginActivity : AppCompatActivity() { | |
| private val viewModel: LoginViewModel by viewModels { | |
| getUserViewModelFactory() | |
| } | |
| private lateinit var googleSignClient: GoogleSignInClient | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| setContentView(R.layout.layout_login) | |
| btn_sign_in_google.setOnClickListener { | |
| viewModel.showLoading(true) | |
| signIn() | |
| } | |
| } | |
| public override fun onStart() { | |
| super.onStart() | |
| setObserverToViewModel() | |
| } | |
| private fun setObserverToViewModel() { | |
| viewModel.apply { | |
| gso.observe(this@LoginActivity, Observer { | |
| googleSignClient = GoogleSignIn.getClient(this@LoginActivity, it) | |
| }) | |
| loading.observe(this@LoginActivity, Observer { | |
| setLoadingView(it) | |
| }) | |
| } | |
| } | |
| public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |
| super.onActivityResult(requestCode, resultCode, data) | |
| if (requestCode == RC_SIGN_IN) { | |
| val task = GoogleSignIn.getSignedInAccountFromIntent(data) | |
| try { | |
| val account = task.getResult(ApiException::class.java) | |
| viewModel.login(account!!) | |
| saveLogin() | |
| moveToMainActivity() | |
| finish() | |
| } catch (e: Exception) { | |
| Toast.makeText(this, getString(R.string.check_internet_connection), Toast.LENGTH_SHORT).show() | |
| e.printStackTrace() | |
| } | |
| } | |
| viewModel.showLoading(false) | |
| } | |
| private fun signIn() { | |
| val signInIntent = googleSignClient.signInIntent | |
| startActivityForResult(signInIntent, RC_SIGN_IN) | |
| } | |
| private fun saveLogin() { | |
| Preferences(this).setLogin(true) | |
| } | |
| private fun moveToMainActivity() { | |
| startActivity(Intent(this, MainActivity::class.java)) | |
| finish() | |
| } | |
| private fun setLoadingView(statusLoading: Boolean) { | |
| if (statusLoading) { | |
| please_wait.visibility = View.VISIBLE | |
| login_loading.visibility = View.VISIBLE | |
| } else { | |
| please_wait.visibility = View.GONE | |
| login_loading.visibility = View.GONE | |
| } | |
| } | |
| companion object { | |
| private const val RC_SIGN_IN = 7 | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.login | |
| import androidx.lifecycle.LiveData | |
| import androidx.lifecycle.MutableLiveData | |
| import androidx.lifecycle.ViewModel | |
| import androidx.lifecycle.viewModelScope | |
| import com.google.android.gms.auth.api.signin.GoogleSignInAccount | |
| import com.google.android.gms.auth.api.signin.GoogleSignInOptions | |
| import id.diamondsleep.data.source.datauser.UserDataContract | |
| import id.diamondsleep.model.User | |
| import kotlinx.coroutines.launch | |
| class LoginViewModel internal constructor(val userRepository: UserDataContract) : ViewModel() { | |
| private val _gso = MutableLiveData<GoogleSignInOptions>() | |
| val gso: LiveData<GoogleSignInOptions> = _gso | |
| private val _loading = MutableLiveData<Boolean>() | |
| val loading: LiveData<Boolean> = _loading | |
| init { | |
| _loading.value = false | |
| _gso.value = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) | |
| .requestEmail() | |
| .build() | |
| } | |
| fun login(googleSignInAccount: GoogleSignInAccount) { | |
| _loading.value = true | |
| viewModelScope.launch { | |
| userRepository.getUser(googleSignInAccount.email!!, googleSignInAccount.displayName!!) | |
| userRepository.saveUser(User(googleSignInAccount.email!!, googleSignInAccount.displayName!!)) | |
| } | |
| _loading.value = false | |
| } | |
| fun showLoading(statusLoading: Boolean) { | |
| _loading.value = statusLoading | |
| } | |
| //for testing purpose | |
| fun loginTest(email: String, displayName: String) { | |
| _loading.value = true | |
| viewModelScope.launch { | |
| userRepository.saveUser(User(email, displayName)) | |
| } | |
| _loading.value = false | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep | |
| import android.content.Intent | |
| import android.os.Bundle | |
| import android.view.MenuItem | |
| import android.widget.Toast | |
| import androidx.appcompat.app.AppCompatActivity | |
| import androidx.appcompat.widget.Toolbar | |
| import androidx.drawerlayout.widget.DrawerLayout | |
| import androidx.navigation.findNavController | |
| import androidx.navigation.ui.AppBarConfiguration | |
| import androidx.navigation.ui.navigateUp | |
| import androidx.navigation.ui.setupActionBarWithNavController | |
| import androidx.navigation.ui.setupWithNavController | |
| import com.google.android.material.navigation.NavigationView | |
| import com.spotify.sdk.android.authentication.AuthenticationClient | |
| import com.spotify.sdk.android.authentication.AuthenticationRequest | |
| import com.spotify.sdk.android.authentication.AuthenticationResponse | |
| import id.diamondsleep.ui.login.LoginActivity | |
| import id.diamondsleep.utilities.ConstantValue.REQUEST_CONNECT_SPOTIFY | |
| import id.diamondsleep.utilities.Preferences | |
| import kotlinx.android.synthetic.main.app_bar_main.* | |
| import timber.log.Timber | |
| class MainActivity : AppCompatActivity() { | |
| private lateinit var appBarConfiguration: AppBarConfiguration | |
| private lateinit var navView: NavigationView | |
| lateinit var drawerLayout: DrawerLayout | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| setContentView(R.layout.main) | |
| val toolbar: Toolbar = findViewById(R.id.toolbar) | |
| setSupportActionBar(toolbar) | |
| loginCheckIn() | |
| navView = findViewById(R.id.nav_view) | |
| drawerLayout = findViewById(R.id.drawer_layout) | |
| setNavigationController() | |
| spotifyAuthorization() | |
| } | |
| private fun spotifyAuthorization() { | |
| if (Preferences(this).getTokenSpotify() == "") { | |
| val builder = AuthenticationRequest.Builder(BuildConfig.SPOTIFY_CLIENT_ID, AuthenticationResponse.Type.TOKEN, BuildConfig.SPOTIFY_REDIRECT_URI) | |
| builder.setScopes(arrayOf("streaming")) | |
| sendToActivityResultForConnectSpotify(builder) | |
| } | |
| } | |
| private fun sendToActivityResultForConnectSpotify(builder: AuthenticationRequest.Builder) { | |
| val request = builder.build() | |
| AuthenticationClient.openLoginActivity(this, REQUEST_CONNECT_SPOTIFY, request) | |
| } | |
| override fun onSupportNavigateUp(): Boolean { | |
| val navController = findNavController(R.id.nav_host_fragment) | |
| return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() | |
| } | |
| private fun setNavigationController() { | |
| val navController = findNavController(R.id.nav_host_fragment) | |
| appBarConfiguration = AppBarConfiguration( | |
| setOf( | |
| R.id.nav_home, R.id.nav_relaxation, R.id.nav_environment_conditions, | |
| R.id.nav_hitung_kualitastidur, R.id.nav_datatidur, R.id.nav_setting, | |
| R.id.nav_about_app, R.id.nav_logout | |
| ), drawerLayout | |
| ) | |
| setupActionBarWithNavController(navController, appBarConfiguration) | |
| navView.setupWithNavController(navController) | |
| } | |
| private fun loginCheckIn() { | |
| if (!Preferences(this).isLogin()) { | |
| moveToLoginActivity() | |
| } | |
| } | |
| private fun moveToLoginActivity() { | |
| startActivity(Intent(this, LoginActivity::class.java)) | |
| finish() | |
| } | |
| override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |
| super.onActivityResult(requestCode, resultCode, data) | |
| if (requestCode == REQUEST_CONNECT_SPOTIFY) { | |
| onConnectingSpotify(resultCode, data) | |
| } | |
| } | |
| private fun onConnectingSpotify(resultCode: Int, data: Intent?) { | |
| val response = AuthenticationClient.getResponse(resultCode, data) | |
| when (response.type) { | |
| AuthenticationResponse.Type.TOKEN -> { | |
| Preferences(this).saveTokenSpotify(response.accessToken) | |
| } | |
| AuthenticationResponse.Type.ERROR -> { | |
| Timber.d("erroreuy: "+response.error) | |
| Toast.makeText(this, response.error, Toast.LENGTH_SHORT).show() | |
| } | |
| else -> { | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.home.tips | |
| import id.diamondsleep.model.CategoryTips | |
| import id.diamondsleep.model.Tip | |
| object MapToCategoryTips { | |
| fun convert(tips: List<Tip>): List<CategoryTips> { | |
| val categoryTips = mutableListOf<CategoryTips>() | |
| val tipsByCategory = tips.groupBy { it.category } | |
| for (value in tipsByCategory.values) { | |
| val categoryName = value[0].category.replace("_", " ") | |
| categoryTips.add(CategoryTips(categoryName, value)) | |
| } | |
| return categoryTips | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.utilities.backgroundservice | |
| import android.app.Service | |
| import android.content.Intent | |
| import android.os.IBinder | |
| import id.diamondsleep.R | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.utilities.NoiseDetection | |
| import id.diamondsleep.utilities.SleepyNotification | |
| import java.util.* | |
| import kotlin.math.roundToInt | |
| class NoiseService : Service() { | |
| private var noiseDetection: NoiseDetection? = null | |
| private var soundLevelValueSum = 0 | |
| private val soundLevelTolerance = 80 | |
| private val fiveMinutes = 60 * 5 | |
| private var incrementMillisecond = 0 | |
| override fun onCreate() { | |
| super.onCreate() | |
| noiseDetection = NoiseDetection() | |
| } | |
| override fun onBind(intent: Intent?): IBinder? { | |
| return null | |
| } | |
| override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { | |
| if (intent!!.getBooleanExtra(ConstantValue.DEACTIVE_SERVICE, false)) { | |
| stopSelf() | |
| } | |
| noiseDetection = NoiseDetection() | |
| noiseDetection!!.start() | |
| Timer().scheduleAtFixedRate(object : TimerTask() { | |
| override fun run() { | |
| ++incrementMillisecond | |
| if (incrementMillisecond == 10 && isFirstValueChanged) { | |
| showSoundLevelDisturbingNotification() | |
| isFirstValueChanged = false | |
| } | |
| if (!noiseDetection!!.amplitude.isNaN()){ | |
| soundLevelValueSum += noiseDetection!!.amplitude.roundToInt() | |
| } | |
| showNotificationIfSoundDistrubing() | |
| } | |
| }, 0, 1000) | |
| return START_NOT_STICKY | |
| } | |
| private fun showNotificationIfSoundDistrubing() { | |
| if (incrementMillisecond == fiveMinutes) { | |
| incrementMillisecond = 0 | |
| val meanSoundValue = soundLevelValueSum / fiveMinutes | |
| if (meanSoundValue > soundLevelTolerance) { | |
| showSoundLevelDisturbingNotification() | |
| } | |
| } | |
| } | |
| private fun showSoundLevelDisturbingNotification() { | |
| val notification = SleepyNotification(this@NoiseService) | |
| notification.apply { | |
| // title = "Noise Level ${noiseDetection!!.amplitude.roundToInt()} dB" | |
| title = "Noise Level 33 dB" | |
| message = getString(R.string.message_for_turnoff_sound_disturbing) | |
| showNotification() | |
| } | |
| } | |
| override fun onDestroy() { | |
| super.onDestroy() | |
| noiseDetection!!.stop() | |
| } | |
| companion object { | |
| var isFirstValueChanged = true | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.sleepqualitycalculator | |
| import android.os.Bundle | |
| import android.view.View | |
| interface QuestionsView { | |
| fun setContentView(view: View) | |
| fun moveToNext(view: View) | |
| fun moveToBack(view: View) | |
| fun answeredQuestions(view: View): Bundle | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data.remoteapi | |
| import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory | |
| import id.diamondsleep.BuildConfig | |
| import okhttp3.OkHttpClient | |
| import okhttp3.logging.HttpLoggingInterceptor | |
| import retrofit2.Retrofit | |
| import retrofit2.converter.gson.GsonConverterFactory | |
| object RetrofitFactory { | |
| private val mLoggingInterceptor = HttpLoggingInterceptor() | |
| private val client: OkHttpClient = | |
| OkHttpClient.Builder().addInterceptor(mLoggingInterceptor).build() | |
| init { | |
| mLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY | |
| } | |
| private val retrofit: Retrofit = Retrofit.Builder() | |
| .baseUrl(BuildConfig.BASE_URL) | |
| .client(client) | |
| .addConverterFactory(GsonConverterFactory.create()) | |
| .addCallAdapterFactory(CoroutineCallAdapterFactory()) | |
| .build() | |
| val USER_API: UserApi = retrofit.create(UserApi::class.java) | |
| val TIPS_API: TipsApi = retrofit.create(TipsApi::class.java) | |
| val ARTICLE_API: ArticleApi = retrofit.create(ArticleApi::class.java) | |
| val SLEEP_QUALITY_CALCULATOR_API: SleepQualityCalculatorApi = retrofit.create(SleepQualityCalculatorApi::class.java) | |
| val SLEEP_HISTORY: SleepHistoryApi = retrofit.create(SleepHistoryApi::class.java) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.sleepqualitycalculator | |
| 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.fragment.app.viewModels | |
| import id.diamondsleep.R | |
| import id.diamondsleep.getSleepQualityViewModelFactory | |
| import id.diamondsleep.utilities.psqiutil.PSQIQualityCalculator | |
| import id.diamondsleep.model.PSQISleepQuality | |
| import id.diamondsleep.ui.home.tips.tipsmore.AllTipsActivity | |
| import id.diamondsleep.utilities.DateUtilities | |
| import id.diamondsleep.utilities.CategoryTipsValue | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.model.psqiquestions.PSQIQualityQuestions | |
| import kotlinx.android.synthetic.main.layout_psqi_result.view.* | |
| class SleepQualityCalculationScoreFragment : Fragment() { | |
| private val viewModel: SleepQualityCalculatorViewModel by viewModels { | |
| getSleepQualityViewModelFactory() | |
| } | |
| private var sleepSubjectiveScore = 0 | |
| private var sleepLatencyScore = 0 | |
| private var sleepDurationScore = 0 | |
| private var sleepEfficiencyScore = 0 | |
| private var sleepDisturbingScore = 0 | |
| private var medicamentUsingScore = 0 | |
| private var daytimeDysfunctionScore = 0 | |
| private var psqiScore = 0 | |
| private lateinit var psqiSLeepQuality: PSQIQualityQuestions | |
| override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { | |
| val view = inflater.inflate(R.layout.layout_psqi_result, container, false) | |
| psqiSLeepQuality = getAnsweredQuestionsBefore() | |
| setupScore() | |
| setupScoreView(view) | |
| saveScoreToServer() | |
| view.sleep_quality_scoring_button.setOnClickListener { | |
| val intent = Intent(requireActivity(), AllTipsActivity::class.java) | |
| intent.putExtra(AllTipsActivity.CATEGORY_KEY, CategoryTipsValue.getCategoryIndex("")) | |
| startActivity(intent) | |
| } | |
| return view | |
| } | |
| private fun setupScore() { | |
| val psqiCalculator = PSQIQualityCalculator(psqiSLeepQuality) | |
| psqiCalculator.apply { | |
| sleepSubjectiveScore = sleepSubjectiveScore() | |
| sleepLatencyScore = sleepLatencyScore() | |
| sleepDurationScore = sleepDurationScore() | |
| sleepEfficiencyScore = sleepEfficiencyScore() | |
| sleepDisturbingScore = sleepDisturbingScore() | |
| medicamentUsingScore = medicamentUsingScore() | |
| daytimeDysfunctionScore = daytimeDysfunctionScore() | |
| psqiScore = psqiSleepQualityScore() | |
| } | |
| } | |
| private fun saveScoreToServer() { | |
| val psqiSleepQuality = PSQISleepQuality( | |
| 0, | |
| "", | |
| sleepSubjectiveScore, | |
| sleepDurationScore, | |
| sleepLatencyScore, | |
| sleepEfficiencyScore, | |
| sleepDisturbingScore, | |
| medicamentUsingScore, | |
| daytimeDysfunctionScore, | |
| DateUtilities.getCurrentDate() | |
| ) | |
| viewModel.saveSleepQuality(psqiSleepQuality) | |
| } | |
| private fun setupScoreView(view: View) { | |
| view.apply { | |
| sleepquality_count_subjective_score.text = sleepSubjectiveScore.toString() | |
| sleepquality_count_latency_score.text = sleepLatencyScore.toString() | |
| sleepquality_count_duration_score.text = sleepDurationScore.toString() | |
| sleepquality_count_efficiency_score.text = sleepEfficiencyScore.toString() | |
| sleepquality_count_disturb_score.text = sleepDisturbingScore.toString() | |
| sleepquality_count_medicament_score.text = medicamentUsingScore.toString() | |
| sleepquality_count_dysfunction_score.text = daytimeDysfunctionScore.toString() | |
| sleep_quality_score.text = psqiScore.toString() | |
| sleep_quality_result.text = resultSleepQuality(psqiScore) | |
| } | |
| } | |
| private fun resultSleepQuality(sleepQualityScore: Int): String { | |
| return if (sleepQualityScore <= 5) { | |
| requireContext().getString(R.string.the_conclusion_is_good_sleep_quality) | |
| } else { | |
| requireContext().getString(R.string.the_conclusion_is_poor_sleep_quality) | |
| } | |
| } | |
| private fun getAnsweredQuestionsBefore(): PSQIQualityQuestions { | |
| return arguments?.getParcelable(ConstantValue.DATA_QUESTIONS_SLEEP_QUALITY)!! | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.sleepqualitycalculator | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import androidx.recyclerview.widget.RecyclerView | |
| import com.bumptech.glide.Glide | |
| import id.diamondsleep.R | |
| import id.diamondsleep.model.PSQISleepQuality | |
| import id.diamondsleep.utilities.DateConverter | |
| import kotlinx.android.synthetic.main.card_sleepqualitycount.view.* | |
| class SleepQualityCalculatorAdapter : RecyclerView.Adapter<SleepQualityCalculatorAdapter.ViewHolder>() { | |
| private val psqiSleepQualities = mutableListOf<PSQISleepQuality>() | |
| fun updateSleepQualityCountAdapter(sleepQualities: List<PSQISleepQuality>) { | |
| this.psqiSleepQualities.clear() | |
| this.psqiSleepQualities.addAll(sleepQualities) | |
| notifyDataSetChanged() | |
| } | |
| override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { | |
| return ViewHolder( | |
| LayoutInflater.from(parent.context).inflate(R.layout.card_sleepqualitycount, parent, false) | |
| ) | |
| } | |
| override fun getItemCount(): Int { | |
| return psqiSleepQualities.size | |
| } | |
| override fun onBindViewHolder(holder: ViewHolder, position: Int) { | |
| holder.bindItem(psqiSleepQualities[position]) | |
| } | |
| class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { | |
| private val date = itemView.sleepqualitycount_date | |
| private val score = itemView.sleepqualitycount_score | |
| private val iconIndicator = itemView.sleepqualitycount_icon_indicator | |
| private val sleepQualityResult = itemView.sleepqualitycount_sleepquality_result | |
| fun bindItem(psqiSleepQuality: PSQISleepQuality) { | |
| val psqiScore = psqiSleepScore(psqiSleepQuality) | |
| date.text = DateConverter.convertDateToStringWithoutTime(psqiSleepQuality.date) | |
| score.text = psqiScore.toString() | |
| if (psqiScore > 5) { | |
| Glide.with(itemView.context).load(R.mipmap.ic_smile_black).into(iconIndicator) | |
| sleepQualityResult.text = itemView.context.getString(R.string.good) | |
| } else { | |
| Glide.with(itemView.context).load(R.mipmap.ic_sad_black).into(iconIndicator) | |
| sleepQualityResult.text = itemView.context.getString(R.string.not_good) | |
| } | |
| } | |
| fun psqiSleepScore(psqiSleepQuality: PSQISleepQuality): Int { | |
| psqiSleepQuality.apply { | |
| return sleepSubjective + sleepLatency + sleepDuration + sleepHabitsEfficiency + sleepDisturbance + medicamentUse + daytimeDysfunction | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.sleepqualitycalculator | |
| import android.os.Bundle | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import androidx.fragment.app.Fragment | |
| import androidx.fragment.app.viewModels | |
| import androidx.lifecycle.Observer | |
| import androidx.navigation.findNavController | |
| import androidx.recyclerview.widget.DefaultItemAnimator | |
| import androidx.recyclerview.widget.LinearLayoutManager | |
| import id.diamondsleep.MainActivity | |
| import id.diamondsleep.R | |
| import id.diamondsleep.getSleepQualityViewModelFactory | |
| import kotlinx.android.synthetic.main.app_bar_main.* | |
| import kotlinx.android.synthetic.main.layout_sleep_quality_count.* | |
| import kotlinx.android.synthetic.main.layout_sleep_quality_count.view.* | |
| class SleepQualityCalculatorFragment : Fragment() { | |
| private val sleepQualityViewModel: SleepQualityCalculatorViewModel by viewModels { | |
| getSleepQualityViewModelFactory() | |
| } | |
| private lateinit var adapter: SleepQualityCalculatorAdapter | |
| override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, | |
| savedInstanceState: Bundle?): View? { | |
| val view = inflater.inflate(R.layout.layout_sleep_quality_count, container, false) | |
| (requireActivity() as MainActivity).toolbar_point.text = getText(R.string.nav_item_sleepqualitycount) | |
| adapter = SleepQualityCalculatorAdapter() | |
| setSleepQualityHistoryRecyclerView(view) | |
| view.sleepqualitycount_btn_startcounting.setOnClickListener { | |
| it.findNavController().navigate(R.id.action_nav_hitung_kualitastidur_to_sleepQualityCountQuestionZero) | |
| } | |
| return view | |
| } | |
| override fun onStart() { | |
| super.onStart() | |
| setObserverToViewModel() | |
| } | |
| private fun setObserverToViewModel() { | |
| sleepQualityViewModel.apply { | |
| psqiSleepQualities.observe(viewLifecycleOwner, Observer { | |
| if (it.isNotEmpty()) { | |
| adapter.updateSleepQualityCountAdapter(it) | |
| } else { | |
| sleepqualitycount_nohistory.visibility = View.VISIBLE | |
| } | |
| }) | |
| loading.observe(viewLifecycleOwner, Observer { | |
| loadingState(it) | |
| }) | |
| } | |
| } | |
| private fun setSleepQualityHistoryRecyclerView(view: View) { | |
| view.recyclerview_sleepquality_history.apply { | |
| layoutManager = LinearLayoutManager(requireContext()) | |
| adapter = this@SleepQualityCalculatorFragment.adapter | |
| itemAnimator = DefaultItemAnimator() | |
| } | |
| } | |
| private fun loadingState(statusLoading: Boolean) { | |
| if (statusLoading) { | |
| sleepqualitycount_proggressbar.visibility = View.VISIBLE | |
| } else { | |
| sleepqualitycount_proggressbar.visibility = View.GONE | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.sleepqualitycalculator.questions | |
| import android.os.Bundle | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import android.widget.ArrayAdapter | |
| import androidx.core.os.bundleOf | |
| import androidx.fragment.app.Fragment | |
| import androidx.navigation.findNavController | |
| import id.diamondsleep.R | |
| import id.diamondsleep.ui.sleepqualitycalculator.QuestionsView | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.model.psqiquestions.DailyLife | |
| import id.diamondsleep.model.psqiquestions.PSQIQualityQuestions | |
| import kotlinx.android.synthetic.main.layout_sleepquality_questions.view.* | |
| import kotlinx.android.synthetic.main.sleepquality_question_four.view.* | |
| class SleepQualityCountQuestionFourFragment : Fragment(), QuestionsView { | |
| private lateinit var psqiSLeepQuality: PSQIQualityQuestions | |
| override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { | |
| val view = inflater.inflate(R.layout.layout_sleepquality_questions, container, false) | |
| setContentView(view) | |
| setAnswerQuestions(view) | |
| psqiSLeepQuality = getAnsweredQuestionsBefore() | |
| view.sleepqualitycount_question_next_btn.setOnClickListener { | |
| moveToNext(view) | |
| } | |
| return view | |
| } | |
| override fun answeredQuestions(view: View): Bundle { | |
| val dailyLife = DailyLife() | |
| dailyLife.apply { | |
| sleepQualityToLifeAnswer = view.sleepqualitycount_question_about_sleepquality_tolife_answer.selectedItemPosition | |
| affectSleepQualityAnswer = view.sleepqualitycount_question_about_sleepquality_towork_answer.selectedItemPosition | |
| } | |
| psqiSLeepQuality.dailyLife = dailyLife | |
| return bundleOf(ConstantValue.DATA_QUESTIONS_SLEEP_QUALITY to psqiSLeepQuality) | |
| } | |
| private fun setAnswerQuestions(view: View) { | |
| ArrayAdapter.createFromResource( | |
| requireContext(), | |
| R.array.sleep_quality_common_answer, | |
| android.R.layout.simple_spinner_item | |
| ).also { adapter -> | |
| adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) | |
| view.sleepqualitycount_question_about_sleepquality_tolife_answer.adapter = adapter | |
| view.sleepqualitycount_question_about_sleepquality_towork_answer.adapter = adapter | |
| } | |
| } | |
| private fun getAnsweredQuestionsBefore(): PSQIQualityQuestions { | |
| return arguments?.getParcelable(ConstantValue.DATA_QUESTIONS_SLEEP_QUALITY)!! | |
| } | |
| override fun setContentView(view: View) { | |
| view.sleepqualitycount_question_questiontext.visibility = View.GONE | |
| view.sleepqualitycount_question_viewstub.apply { | |
| this.layoutResource = R.layout.sleepquality_question_four | |
| this.inflate() | |
| } | |
| view.sleepqualitycount_question_proggresspageindicator.progress = 100 | |
| view.sleepqualitycount_question_current_page.text = 5.toString() | |
| view.sleepqualitycount_question_questiontext.text = requireContext().getText(R.string.sleep_quality_count_question_about_sleep_disorders) | |
| view.sleepqualitycount_question_explanation.text = requireContext().getText(R.string.sleep_quality_count_question_sleep_disoders_explanation) | |
| } | |
| override fun moveToNext(view: View) { | |
| view.findNavController().navigate(R.id.action_sleepQualityCountQuestionFourFragment_to_sleepQualityCountScoreSleepQualityFragment, | |
| answeredQuestions(view)) | |
| } | |
| override fun moveToBack(view: View) { | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.sleepqualitycalculator.questions | |
| import android.os.Bundle | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import android.widget.RadioButton | |
| import androidx.core.os.bundleOf | |
| import androidx.fragment.app.Fragment | |
| import androidx.navigation.findNavController | |
| import id.diamondsleep.R | |
| import id.diamondsleep.ui.sleepqualitycalculator.QuestionsView | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.model.psqiquestions.PSQIQualityQuestions | |
| import kotlinx.android.synthetic.main.layout_sleepquality_questions.view.* | |
| import kotlinx.android.synthetic.main.sleepquality_question_one.view.* | |
| class SleepQualityCountQuestionOneFragment : Fragment(), QuestionsView { | |
| private lateinit var psqiSLeepQuality: PSQIQualityQuestions | |
| override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { | |
| val view = inflater.inflate(R.layout.layout_sleepquality_questions, container, false) | |
| setContentView(view) | |
| psqiSLeepQuality = getAnsweredQuestionsBefore() | |
| view.sleepqualitycount_question_next_btn.setOnClickListener { | |
| moveToNext(view) | |
| } | |
| return view | |
| } | |
| private fun getAnsweredQuestionsBefore(): PSQIQualityQuestions { | |
| return arguments?.getParcelable(ConstantValue.DATA_QUESTIONS_SLEEP_QUALITY)!! | |
| } | |
| override fun moveToNext(view: View) { | |
| view.findNavController().navigate(R.id.action_sleepQualityCountQuestionOneFragment_to_sleepQualityCountQuestionTwoFragment, | |
| answeredQuestions(view)) | |
| } | |
| override fun moveToBack(view: View) { | |
| } | |
| private fun selectedAnswer(view: View): Int { | |
| view.radioGroupLastSleepQuality.apply { | |
| val selectedAnswerId = this.checkedRadioButtonId | |
| val selectedButton = this.findViewById<RadioButton>(selectedAnswerId) | |
| return indexOfChild(selectedButton) | |
| } | |
| } | |
| override fun answeredQuestions(view: View): Bundle { | |
| psqiSLeepQuality.lastSleepQualityAnswer = selectedAnswer(view) | |
| return bundleOf(ConstantValue.DATA_QUESTIONS_SLEEP_QUALITY to psqiSLeepQuality) | |
| } | |
| override fun setContentView(view: View) { | |
| view.sleepqualitycount_question_viewstub.apply { | |
| this.layoutResource = R.layout.sleepquality_question_one | |
| this.inflate() | |
| } | |
| view.sleepqualitycount_question_proggresspageindicator.progress = 40 | |
| view.sleepqualitycount_question_current_page.text = 2.toString() | |
| view.sleepqualitycount_question_explanation.text = requireContext().getText(R.string.sleep_quality_count_question_how_good_quality_of_sleep_explanation) | |
| view.sleepqualitycount_question_questiontext.text = requireContext().getText(R.string.sleep_quality_count_question_how_good_quality_of_sleep) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.sleepqualitycalculator.questions | |
| import android.os.Bundle | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import android.widget.ArrayAdapter | |
| import androidx.core.os.bundleOf | |
| import androidx.fragment.app.Fragment | |
| import androidx.navigation.findNavController | |
| import id.diamondsleep.R | |
| import id.diamondsleep.ui.sleepqualitycalculator.QuestionsView | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.model.psqiquestions.PSQIQualityQuestions | |
| import kotlinx.android.synthetic.main.layout_sleepquality_questions.view.* | |
| import kotlinx.android.synthetic.main.sleepquality_question_three.view.* | |
| class SleepQualityCountQuestionThreeFragment : Fragment(), QuestionsView { | |
| private lateinit var psqiSLeepQuality: PSQIQualityQuestions | |
| override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { | |
| val view = inflater.inflate(R.layout.layout_sleepquality_questions, container, false) | |
| setContentView(view) | |
| setAnswerQuestions(view) | |
| psqiSLeepQuality = getAnsweredQuestionsBefore() | |
| view.sleepqualitycount_question_next_btn.setOnClickListener { | |
| moveToNext(view) | |
| } | |
| return view | |
| } | |
| private fun getAnsweredQuestionsBefore(): PSQIQualityQuestions { | |
| return arguments?.getParcelable(ConstantValue.DATA_QUESTIONS_SLEEP_QUALITY)!! | |
| } | |
| override fun setContentView(view: View) { | |
| view.sleepqualitycount_question_viewstub.apply { | |
| this.layoutResource = R.layout.sleepquality_question_three | |
| this.inflate() | |
| } | |
| view.sleepqualitycount_question_proggresspageindicator.progress = 80 | |
| view.sleepqualitycount_question_current_page.text = 4.toString() | |
| view.sleepqualitycount_question_questiontext.text = requireContext().getText(R.string.question_used_medicine) | |
| view.sleepqualitycount_question_explanation.text = requireContext().getText(R.string.sleep_quality_count_question_sleep_disoders_explanation) | |
| } | |
| override fun moveToNext(view: View) { | |
| view.findNavController().navigate(R.id.action_sleepQualityCountQuestionThreeFragment_to_sleepQualityCountQuestionFourFragment, | |
| answeredQuestions(view)) | |
| } | |
| override fun moveToBack(view: View) { | |
| } | |
| override fun answeredQuestions(view: View): Bundle { | |
| psqiSLeepQuality.usingMedicament = view.sleepqualitycount_question_medicament_answer.selectedItemPosition | |
| return bundleOf(ConstantValue.DATA_QUESTIONS_SLEEP_QUALITY to psqiSLeepQuality) | |
| } | |
| private fun setAnswerQuestions(view: View) { | |
| ArrayAdapter.createFromResource( | |
| requireContext(), | |
| R.array.medicament_use_answer, | |
| android.R.layout.simple_spinner_item | |
| ).also { adapter -> | |
| adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) | |
| view.sleepqualitycount_question_medicament_answer.adapter = adapter | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.sleepqualitycalculator.questions | |
| import android.os.Bundle | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import android.widget.ArrayAdapter | |
| import androidx.core.os.bundleOf | |
| import androidx.fragment.app.Fragment | |
| import androidx.navigation.findNavController | |
| import id.diamondsleep.R | |
| import id.diamondsleep.ui.sleepqualitycalculator.QuestionsView | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.model.psqiquestions.PSQIQualityQuestions | |
| import id.diamondsleep.model.psqiquestions.SleepDisorders | |
| import kotlinx.android.synthetic.main.layout_sleepquality_questions.view.* | |
| import kotlinx.android.synthetic.main.sleepquality_question_two.view.* | |
| /** | |
| * A simple [Fragment] subclass. | |
| */ | |
| class SleepQualityCountQuestionTwoFragment : Fragment(), QuestionsView { | |
| private lateinit var psqiSLeepQuality: PSQIQualityQuestions | |
| override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { | |
| val view = inflater.inflate(R.layout.layout_sleepquality_questions, container, false) | |
| setContentView(view) | |
| setAnswerQuestions(view) | |
| psqiSLeepQuality = getAnsweredQuestionsBefore() | |
| view.sleepqualitycount_question_next_btn.setOnClickListener { | |
| moveToNext(view) | |
| } | |
| return view | |
| } | |
| override fun moveToNext(view: View) { | |
| view.findNavController().navigate(R.id.action_sleepQualityCountQuestionTwoFragment_to_sleepQualityCountQuestionThreeFragment, | |
| answeredQuestions(view)) | |
| } | |
| override fun moveToBack(view: View) { | |
| } | |
| private fun getAnsweredQuestionsBefore(): PSQIQualityQuestions { | |
| return arguments?.getParcelable(ConstantValue.DATA_QUESTIONS_SLEEP_QUALITY)!! | |
| } | |
| override fun answeredQuestions(view: View): Bundle { | |
| val sleepDisorders = SleepDisorders() | |
| // create sleep disorders | |
| sleepDisorders.apply { | |
| cantSleepIn30MinutesAnswer = view.sleepqualitycount_question_cant_sleep_30minutes_answer.selectedItemPosition | |
| wakeupMidnightAnswer = view.sleepqualitycount_question_wakeup_midnight_answer.selectedItemPosition | |
| wakeupForBathroomAnswer = view.sleepqualitycount_question_wakeup_bathroom_answer.selectedItemPosition | |
| cantBreatheBetterAnswer = view.sleepqualitycount_question_cant_breathe_better_answer.selectedItemPosition | |
| coughSnoreAnsweer = view.sleepqualitycount_question_cough_snore_answer.selectedItemPosition | |
| } | |
| // sleep disoders to psqiSleepQuality | |
| psqiSLeepQuality.sleepDisorders = sleepDisorders | |
| return bundleOf(ConstantValue.DATA_QUESTIONS_SLEEP_QUALITY to psqiSLeepQuality) | |
| } | |
| override fun setContentView(view: View) { | |
| view.sleepqualitycount_question_viewstub.apply { | |
| this.layoutResource = R.layout.sleepquality_question_two | |
| this.inflate() | |
| } | |
| view.sleepqualitycount_question_proggresspageindicator.progress = 60 | |
| view.sleepqualitycount_question_current_page.text = 3.toString() | |
| view.sleepqualitycount_question_questiontext.text = requireContext().getText(R.string.sleep_quality_count_question_about_sleep_disorders) | |
| view.sleepqualitycount_question_explanation.text = requireContext().getText(R.string.sleep_quality_count_question_sleep_disoders_explanation) | |
| } | |
| private fun setAnswerQuestions(view: View) { | |
| ArrayAdapter.createFromResource( | |
| requireContext(), | |
| R.array.time_disorders_sleep_answer, | |
| android.R.layout.simple_spinner_item | |
| ).also { adapter -> | |
| adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) | |
| view.sleepqualitycount_question_cant_sleep_30minutes_answer.adapter = adapter | |
| view.sleepqualitycount_question_cant_breathe_better_answer.adapter = adapter | |
| view.sleepqualitycount_question_cough_snore_answer.adapter = adapter | |
| view.sleepqualitycount_question_wakeup_bathroom_answer.adapter = adapter | |
| view.sleepqualitycount_question_wakeup_midnight_answer.adapter = adapter | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.data | |
| import androidx.room.Database | |
| import androidx.room.RoomDatabase | |
| import id.diamondsleep.data.source.dataarticle.articlelocal.ArticleDao | |
| import id.diamondsleep.data.source.dataarticle.articlelocal.ArticleLocal | |
| import id.diamondsleep.data.source.datapsqisleepquality.psqisleepqualitylocal.PSQISleepQualityDao | |
| import id.diamondsleep.data.source.datapsqisleepquality.psqisleepqualitylocal.PSQISleepQualityLocal | |
| import id.diamondsleep.data.source.datasleephistory.sleephistorylocal.SleepHistoryDao | |
| import id.diamondsleep.data.source.datasleephistory.sleephistorylocal.SleepHistoryLocal | |
| import id.diamondsleep.data.source.datatips.tipslocal.TipsDao | |
| import id.diamondsleep.data.source.datatips.tipslocal.TipLocal | |
| import id.diamondsleep.data.source.datauser.local.UserDao | |
| import id.diamondsleep.data.source.datauser.local.UserLocal | |
| @Database( | |
| entities = [UserLocal::class, TipLocal::class, ArticleLocal::class, PSQISleepQualityLocal::class, SleepHistoryLocal::class], | |
| version = 2, | |
| exportSchema = true | |
| ) | |
| abstract class SleepyDatabase : RoomDatabase() { | |
| abstract fun userDao(): UserDao | |
| abstract fun tipsDao(): TipsDao | |
| abstract fun articelDao(): ArticleDao | |
| abstract fun psqiSleepQualityDao(): PSQISleepQualityDao | |
| abstract fun sleepHistoryDao(): SleepHistoryDao | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.home.tips | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import androidx.recyclerview.widget.RecyclerView | |
| import com.bumptech.glide.Glide | |
| import com.bumptech.glide.load.resource.bitmap.RoundedCorners | |
| import com.bumptech.glide.request.RequestOptions | |
| import id.diamondsleep.R | |
| import id.diamondsleep.model.Tip | |
| import id.diamondsleep.utilities.OnCardClickListener | |
| import id.diamondsleep.utilities.helper.StringToDateConverter | |
| import kotlinx.android.synthetic.main.card_tips.view.* | |
| class TipsCardAdapter( | |
| private var categoryTips: MutableList<Tip> = mutableListOf(), | |
| private val cardClickListener: OnCardClickListener<Tip> | |
| ) : RecyclerView.Adapter<TipsCardAdapter.ViewHolder>() { | |
| fun update(tips: List<Tip>) { | |
| categoryTips.clear() | |
| categoryTips.addAll(tips) | |
| notifyDataSetChanged() | |
| } | |
| override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { | |
| return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.card_tips, parent, false)) | |
| } | |
| override fun getItemCount(): Int = categoryTips.size | |
| override fun onBindViewHolder(holder: ViewHolder, position: Int) { | |
| holder.bindItem(categoryTips[position], cardClickListener) | |
| } | |
| class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { | |
| private val thumbnailImage = itemView.tips_child_thumbnail | |
| private val title = itemView.tips_child_title | |
| private val author = itemView.tips_child_author | |
| private val date = itemView.tips_child_date | |
| fun bindItem(tip: Tip, listener: OnCardClickListener<Tip>) { | |
| Glide.with(itemView).load(tip.imageUrl).apply(RequestOptions.bitmapTransform(RoundedCorners(24))).into(thumbnailImage) | |
| title.text = tip.title | |
| author.text = tip.author | |
| date.text = StringToDateConverter.changeFormatDate(tip.date) | |
| itemView.setOnClickListener { | |
| listener.onClicked(tip) | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.home.tips | |
| import android.content.Context | |
| import android.content.Intent | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import android.widget.ImageView | |
| import android.widget.RelativeLayout | |
| import android.widget.TextView | |
| import androidx.viewpager.widget.PagerAdapter | |
| import com.bumptech.glide.Glide | |
| import com.google.gson.Gson | |
| import id.diamondsleep.R | |
| import id.diamondsleep.model.Tip | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.utilities.OnCardClickListener | |
| class TipsCarouselAdapter( | |
| private val context: Context, | |
| private val onCardClickListener: OnCardClickListener<Tip> | |
| ) : PagerAdapter() { | |
| private val mTips: MutableList<Tip> = mutableListOf() | |
| fun update(tips: List<Tip>) { | |
| mTips.clear() | |
| mTips.addAll(tips) | |
| notifyDataSetChanged() | |
| } | |
| private val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater | |
| override fun getCount(): Int { | |
| return mTips.size | |
| } | |
| override fun instantiateItem(container: ViewGroup, position: Int): Any { | |
| val itemView = inflater.inflate(R.layout.adapter_tips_main_view_pager, container, false) | |
| val tipsTitle: TextView = itemView.findViewById(R.id.tips_top_title) | |
| val tipsCategory: TextView = itemView.findViewById(R.id.tips_top_kategori) | |
| val tipsThumbnail: ImageView = itemView.findViewById(R.id.tips_top_pic) | |
| val tipsMore: TextView = itemView.findViewById(R.id.tips_top_more) | |
| Glide.with(context).load(mTips[position].imageUrl).into(tipsThumbnail) | |
| tipsCategory.text = mTips[position].category.replace("_"," ") | |
| tipsTitle.text = mTips[position].title | |
| tipsMore.setOnClickListener { | |
| onCardClickListener.onClicked(mTips[position]) | |
| } | |
| container.addView(itemView) | |
| return itemView | |
| } | |
| override fun isViewFromObject(view: View, `object`: Any): Boolean { | |
| return view === `object` | |
| } | |
| override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) { | |
| val view = `object` as View | |
| container.removeView(view) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.home.tips | |
| import android.content.Context | |
| import android.content.Intent | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import android.widget.TextView | |
| import androidx.recyclerview.widget.RecyclerView | |
| import id.diamondsleep.R | |
| import id.diamondsleep.model.CategoryTips | |
| import id.diamondsleep.model.Tip | |
| import id.diamondsleep.ui.home.tips.tipsmore.AllTipsActivity | |
| import id.diamondsleep.utilities.CategoryTipsValue | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.utilities.OnCardClickListener | |
| import kotlinx.android.synthetic.main.category_tips.view.* | |
| class TipsCategoryAdapter(private val cardClickListener: OnCardClickListener<Tip>) | |
| : RecyclerView.Adapter<TipsCategoryAdapter.ViewHolder>() { | |
| private val categoryTips = mutableListOf<CategoryTips>() | |
| private val viewPool = RecyclerView.RecycledViewPool() | |
| private lateinit var context: Context | |
| fun update(categoryTips: List<CategoryTips>) { | |
| this.categoryTips.clear() | |
| this.categoryTips.addAll(categoryTips) | |
| notifyDataSetChanged() | |
| } | |
| override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { | |
| context = parent.context | |
| return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.category_tips, parent, false)) | |
| } | |
| override fun getItemCount(): Int { | |
| return categoryTips.size | |
| } | |
| override fun onBindViewHolder(holder: ViewHolder, position: Int) { | |
| holder.bindItem(categoryTips[position]) | |
| holder.recyclerviewTipsChild.apply { | |
| categoryTips[position].apply{ | |
| adapter = TipsCardAdapter(tips.take(2).toMutableList(), cardClickListener) | |
| } | |
| setRecycledViewPool(viewPool) | |
| } | |
| holder.moreTips.setOnClickListener { | |
| moveToAllTips(categoryTips[position].tips) | |
| } | |
| } | |
| private fun moveToAllTips(tips: List<Tip>) { | |
| val intent = Intent(context, AllTipsActivity::class.java) | |
| intent.putParcelableArrayListExtra(ConstantValue.TIPS_KEY_VALUE, castTipsToArrayListTips(tips)) | |
| intent.putExtra(AllTipsActivity.CATEGORY_KEY, CategoryTipsValue.getCategoryIndex(tips[0].category)) | |
| context.startActivity(intent) | |
| } | |
| private fun castTipsToArrayListTips(tips: List<Tip>): ArrayList<Tip> { | |
| val newTips = arrayListOf<Tip>() | |
| newTips.addAll(tips) | |
| return newTips | |
| } | |
| class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { | |
| private val titleCategory = itemView.title_tips_category | |
| val recyclerviewTipsChild: RecyclerView = itemView.recyclerview_tips_child | |
| val moreTips: TextView = itemView.btn_loadMore | |
| fun bindItem(categoryTip: CategoryTips) { | |
| titleCategory.text = categoryTip.categoryName | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.home.tips | |
| import android.content.Intent | |
| import android.os.Bundle | |
| import android.view.LayoutInflater | |
| import android.view.View | |
| import android.view.ViewGroup | |
| import android.widget.Toast | |
| import androidx.fragment.app.Fragment | |
| import androidx.fragment.app.viewModels | |
| import androidx.lifecycle.Observer | |
| import androidx.recyclerview.widget.DefaultItemAnimator | |
| import androidx.recyclerview.widget.LinearLayoutManager | |
| import androidx.viewpager.widget.ViewPager.OnPageChangeListener | |
| import id.diamondsleep.BaseViewContract | |
| import id.diamondsleep.R | |
| import id.diamondsleep.getTipsViewModelFactory | |
| import id.diamondsleep.model.CategoryTips | |
| import id.diamondsleep.model.Tip | |
| import id.diamondsleep.utilities.ConstantValue | |
| import id.diamondsleep.utilities.EventObserver | |
| import id.diamondsleep.utilities.OnCardClickListener | |
| import kotlinx.android.synthetic.main.layout_tips.* | |
| import kotlinx.android.synthetic.main.layout_tips.view.* | |
| class TipsFragment : Fragment(), BaseViewContract { | |
| private lateinit var tipsCarouselAdapter: TipsCarouselAdapter | |
| private lateinit var tipsCategoryAdapter: TipsCategoryAdapter | |
| var currentPage = 0 | |
| private var NUM_PAGES = 3 | |
| var update: Runnable? = null | |
| private val viewModel: TipsViewModel by viewModels { | |
| getTipsViewModelFactory() | |
| } | |
| override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, | |
| savedInstanceState: Bundle?): View? { // Inflate the layout for this fragment | |
| val view = inflater.inflate(R.layout.layout_tips, container, false) | |
| tipsCategoryAdapter = TipsCategoryAdapter(cardClickListener) | |
| tipsCarouselAdapter = TipsCarouselAdapter(requireContext(), cardClickListener) | |
| view.let { | |
| setSwipeRefreshLayout(it) | |
| setTipsRecyclerView(it) | |
| setCarouselTips(it) | |
| } | |
| update = Runnable { | |
| if (currentPage == NUM_PAGES) { | |
| currentPage = 0 | |
| } | |
| viewPager_tips.setCurrentItem(currentPage++, true) | |
| } | |
| return view | |
| } | |
| private fun setCarouselTips(view: View) { | |
| view.viewPager_tips.adapter = tipsCarouselAdapter | |
| view.viewPager_tips_indicator.setViewPager(view.viewPager_tips) | |
| tipsCarouselAdapter.registerDataSetObserver(view.viewPager_tips_indicator.dataSetObserver) | |
| setCarouselTipsListener(view) | |
| } | |
| private fun setCarouselTipsListener(view: View) { | |
| view.viewPager_tips.addOnPageChangeListener(object : OnPageChangeListener { | |
| override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} | |
| override fun onPageSelected(position: Int) { | |
| currentPage = position | |
| } | |
| override fun onPageScrollStateChanged(state: Int) {} | |
| }) | |
| } | |
| private fun setTipsRecyclerView(view: View) { | |
| view.recyclerview_tips.apply { | |
| layoutManager = LinearLayoutManager(requireContext()) | |
| adapter = tipsCategoryAdapter | |
| setHasFixedSize(true) | |
| itemAnimator = DefaultItemAnimator() | |
| } | |
| } | |
| private fun setSwipeRefreshLayout(view: View) { | |
| view.swipe_tips.apply { | |
| isRefreshing = true | |
| setOnRefreshListener { reloadPage() } | |
| setColorSchemeResources(R.color.colorPrimary) | |
| } | |
| } | |
| override fun onStart() { | |
| super.onStart() | |
| subscribeToViewModel() | |
| } | |
| override fun subscribeToViewModel() { | |
| viewModel.apply { | |
| tips.observe(viewLifecycleOwner, Observer { | |
| if (it.isNotEmpty()) { | |
| updateTipsView(MapToCategoryTips.convert(it)) | |
| } | |
| }) | |
| errorMessage.observe(viewLifecycleOwner, EventObserver { errorMessage -> | |
| Toast.makeText(requireContext(), errorMessage, Toast.LENGTH_SHORT).show() | |
| }) | |
| loading.observe(viewLifecycleOwner, Observer { | |
| showLoadingState(it) | |
| }) | |
| } | |
| } | |
| private fun updateTipsView(categoryTips: List<CategoryTips>) { | |
| val tips = mutableListOf<Tip>() | |
| for (tip in categoryTips) { | |
| tips.add(tip.tips[0]) | |
| } | |
| tipsCategoryAdapter.update(categoryTips) | |
| tipsCarouselAdapter.update(tips) | |
| } | |
| override fun showLoadingState(status: Boolean) { | |
| swipe_tips.isRefreshing = status | |
| } | |
| private fun reloadPage() { | |
| clearTips() | |
| viewModel.getTips(0) | |
| recyclerview_tips.visibility = View.VISIBLE | |
| } | |
| private fun clearTips() { | |
| tipsCategoryAdapter.update(listOf()) | |
| tipsCarouselAdapter.update(listOf()) | |
| } | |
| private fun moveToDetail(cardData: Tip) { | |
| val intent = Intent(requireActivity(), DetailTipsActivity::class.java) | |
| intent.putExtra(ConstantValue.DATA_CONTENT, cardData) | |
| startActivity(intent) | |
| } | |
| private val cardClickListener = object : OnCardClickListener<Tip> { | |
| override fun onClicked(cardData: Tip) { | |
| moveToDetail(cardData) | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package id.diamondsleep.ui.home.tips | |
| import androidx.lifecycle.LiveData | |
| import androidx.lifecycle.MutableLiveData | |
| import androidx.lifecycle.ViewModel | |
| import androidx.lifecycle.viewModelScope | |
| import id.diamondsleep.data.source.datatips.TipsRepository | |
| import id.diamondsleep.data.source.datauser.UserRepository | |
| import id.diamondsleep.model.Result | |
| import id.diamondsleep.model.Tip | |
| import id.diamondsleep.utilities.Event | |
| import kotlinx.coroutines.flow.collect | |
| import kotlinx.coroutines.launch | |
| class TipsViewModel( | |
| private val userRepository: UserRepository, | |
| private val tipsRepository: TipsRepository | |
| ) : ViewModel() { | |
| private val _tips = MutableLiveData<List<Tip>>() | |
| val tips: LiveData<List<Tip>> = _tips | |
| private val _errorMessage = MutableLiveData<Event<String>>() | |
| val errorMessage: LiveData<Event<String>> = _errorMessage | |
| private val _loading = MutableLiveData<Boolean>() | |
| val loading: LiveData<Boolean> = _loading | |
| init { | |
| getTips(0) | |
| } | |
| fun getTips(page: Int) { | |
| viewModelScope.launch { | |
| val resultTips = tipsRepository.getTips(page) | |
| resultTips.collect { tipResponse -> | |
| when (tipResponse) { | |
| is Result.Loading -> { | |
| setLoadingStatus(true) | |
| } | |
| is Result.Success -> { | |
| _tips.value = tipResponse.data | |
| setLoadingStatus(false) | |
| } | |
| is Result.Error -> { | |
| _errorMessage.value = Event(tipResponse.exception.localizedMessage) | |
| setLoadingStatus(false) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| private fun setLoadingStatus(statusLoading: Boolean) { | |
| _loading.value = statusLoading | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment