diff --git a/README.md b/README.md index cf520d6..19830fe 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ News App built with JetPack Compose - [Newzz] (https://github.com/Akashkamble/Newzz) - [Newzz-Flutter] (https://github.com/Akashkamble/Newzz-Flutter) -## The app built using MVVM architecture and contains following libraries +## The app contains following libraries -- [Jetpack Compose(v0.1.0-dev12)] (https://developer.android.com/jetpack/compose) (UI) +- [Jetpack Compose(v0.1.0-dev13)] (https://developer.android.com/jetpack/compose) (UI) - [Koin](https://insert-koin.io/) (Dependency Injection) @@ -22,6 +22,8 @@ News App built with JetPack Compose - [Moshi](https://github.com/square/moshi) (Kotlin JSON library for Android from Square) +- [Accompanist](https://github.com/chrisbanes/accompanist/tree/master/coil) (Image Loading with coil) + # Note This repo is missing api key for [newsapi](https://newsapi.org) diff --git a/app/build.gradle b/app/build.gradle index d5a8f9a..5d8510e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,7 +39,7 @@ android { composeOptions { kotlinCompilerVersion "1.3.70-dev-withExperimentalGoogleExtensions-20200424" - kotlinCompilerExtensionVersion "0.1.0-dev12" + kotlinCompilerExtensionVersion "0.1.0-dev13" } } @@ -57,7 +57,7 @@ dependencies { implementation "androidx.ui:ui-tooling:$compose_version" implementation "androidx.ui:ui-livedata:$compose_version" - /* ---------------------JetPack Compose-----------------------------*/ + /* ---------------------LifeCycle Extension-----------------------------*/ implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" @@ -81,7 +81,7 @@ dependencies { implementation 'androidx.browser:browser:1.3.0-alpha01' /*---------------------CoilImageLoader------------------------------*/ - implementation "dev.chrisbanes.accompanist:accompanist-coil:0.1.3" + implementation "dev.chrisbanes.accompanist:accompanist-coil:0.1.5" testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' diff --git a/app/src/main/java/com/akash/newzz_compose/data/apiService/NewsApiService.kt b/app/src/main/java/com/akash/newzz_compose/data/apiservice/NewsApiService.kt similarity index 98% rename from app/src/main/java/com/akash/newzz_compose/data/apiService/NewsApiService.kt rename to app/src/main/java/com/akash/newzz_compose/data/apiservice/NewsApiService.kt index 7f233a6..5770331 100644 --- a/app/src/main/java/com/akash/newzz_compose/data/apiService/NewsApiService.kt +++ b/app/src/main/java/com/akash/newzz_compose/data/apiservice/NewsApiService.kt @@ -1,4 +1,4 @@ -package com.akash.newzz_compose.data.apiService +package com.akash.newzz_compose.data.apiservice /** * Created by Akash on 06/06/20 diff --git a/app/src/main/java/com/akash/newzz_compose/data/repository/NewsRepositoryImpl.kt b/app/src/main/java/com/akash/newzz_compose/data/repository/NewsRepositoryImpl.kt index 9c0e198..0c8a824 100644 --- a/app/src/main/java/com/akash/newzz_compose/data/repository/NewsRepositoryImpl.kt +++ b/app/src/main/java/com/akash/newzz_compose/data/repository/NewsRepositoryImpl.kt @@ -1,6 +1,6 @@ package com.akash.newzz_compose.data.repository -import com.akash.newzz_compose.data.apiService.NewsApiService +import com.akash.newzz_compose.data.apiservice.NewsApiService import com.akash.newzz_compose.data.response.NewsError import com.akash.newzz_compose.data.response.NewsResponse import com.akash.newzz_compose.utils.Result diff --git a/app/src/main/java/com/akash/newzz_compose/di/module.kt b/app/src/main/java/com/akash/newzz_compose/di/module.kt index 4800981..e0d2cbc 100644 --- a/app/src/main/java/com/akash/newzz_compose/di/module.kt +++ b/app/src/main/java/com/akash/newzz_compose/di/module.kt @@ -1,7 +1,7 @@ package com.akash.newzz_compose.di import com.akash.newzz_compose.viewmodel.NewzzViewModel -import com.akash.newzz_compose.data.apiService.NewsApiService +import com.akash.newzz_compose.data.apiservice.NewsApiService import com.akash.newzz_compose.data.repository.NewsRepository import com.akash.newzz_compose.data.repository.NewsRepositoryImpl import com.squareup.moshi.Moshi diff --git a/app/src/main/java/com/akash/newzz_compose/ui/NewzzActivity.kt b/app/src/main/java/com/akash/newzz_compose/ui/NewzzActivity.kt index 219adaf..27e6f09 100644 --- a/app/src/main/java/com/akash/newzz_compose/ui/NewzzActivity.kt +++ b/app/src/main/java/com/akash/newzz_compose/ui/NewzzActivity.kt @@ -2,14 +2,13 @@ package com.akash.newzz_compose.ui import android.os.Bundle import androidx.appcompat.app.AppCompatActivity -import androidx.compose.Model import androidx.ui.core.setContent import androidx.ui.livedata.observeAsState import androidx.ui.material.MaterialTheme import com.akash.newzz_compose.style.darkThemeColor import com.akash.newzz_compose.style.themeColor -import com.akash.newzz_compose.viewmodel.NewzzViewModel import com.akash.newzz_compose.ui.home.Home +import com.akash.newzz_compose.viewmodel.NewzzViewModel import org.koin.android.viewmodel.ext.android.viewModel @@ -20,7 +19,7 @@ class NewzzActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContent { val isDark = viewModel.isDarkTheme.observeAsState(false) - MaterialTheme(colors = if(isDark.value) darkThemeColor else themeColor) { + MaterialTheme(colors = if (isDark.value) darkThemeColor else themeColor) { Home(viewModel) } } diff --git a/app/src/main/java/com/akash/newzz_compose/ui/articleListPage/ArticleListScreen.kt b/app/src/main/java/com/akash/newzz_compose/ui/articlelist/ArticleListScreen.kt similarity index 81% rename from app/src/main/java/com/akash/newzz_compose/ui/articleListPage/ArticleListScreen.kt rename to app/src/main/java/com/akash/newzz_compose/ui/articlelist/ArticleListScreen.kt index cca53cc..40cbbe0 100644 --- a/app/src/main/java/com/akash/newzz_compose/ui/articleListPage/ArticleListScreen.kt +++ b/app/src/main/java/com/akash/newzz_compose/ui/articlelist/ArticleListScreen.kt @@ -1,10 +1,11 @@ -package com.akash.newzz_compose.ui.articleListPage +package com.akash.newzz_compose.ui.articlelist import androidx.compose.Composable import androidx.compose.State import androidx.ui.core.Alignment import androidx.ui.core.ContextAmbient import androidx.ui.core.Modifier +import androidx.ui.foundation.Box import androidx.ui.foundation.Text import androidx.ui.foundation.VerticalScroller import androidx.ui.foundation.clickable @@ -25,20 +26,9 @@ import com.akash.newzz_compose.utils.CustomTabUtil @Composable fun ArticleRow(article: NewsArticle, isDark: State, onClick: () -> Unit) { - Column(modifier = Modifier.padding(start = 10.dp, end = 10.dp, top = 10.dp)) { + Box(modifier = Modifier.clickable(onClick = { onClick() })) { Row( - /* onClick with more than one modifier was not working hence wrapping it with Column - * Tried modifier = Modifier.clickable( - onClick = { - onClick() - } - ).plus(Modifier.padding(start = 10.dp, end = 10.dp, top = 10.dp)) - */ - modifier = Modifier.clickable( - onClick = { - onClick() - } - ), + modifier = Modifier.padding(all = 10.dp), verticalGravity = Alignment.CenterVertically ) { RemoteImage( @@ -76,14 +66,24 @@ fun ArticleList(articles: List, isDark: State) { /** * App crashing while scrolling the AdapterList hence verticalScroller with Columns used. * @see Issue tracker + * Not fixed in version 0.1.0-dev13 */ + + val context = ContextAmbient.current /*AdapterList(data = articles) { article -> - ArticleRow(article = article) + ArticleRow( + article = article, + isDark = isDark, + onClick = { + CustomTabUtil.launch(context, article.url.toString(), isDark.value) + } + ) + HeightSpacer(value = 10.dp) Divider( - color = Color(0xFFDCDCDC) + color = if (isDark.value) dividerColorDark else dividerColor ) }*/ - val context = ContextAmbient.current + VerticalScroller { Column(modifier = Modifier.fillMaxWidth()) { articles.forEach { article -> @@ -94,7 +94,6 @@ fun ArticleList(articles: List, isDark: State) { CustomTabUtil.launch(context, article.url.toString(), isDark.value) } ) - HeightSpacer(value = 10.dp) Divider( color = if (isDark.value) dividerColorDark else dividerColor ) diff --git a/app/src/main/java/com/akash/newzz_compose/ui/common/Common.kt b/app/src/main/java/com/akash/newzz_compose/ui/common/Common.kt index 7e018d5..4cd7f4c 100644 --- a/app/src/main/java/com/akash/newzz_compose/ui/common/Common.kt +++ b/app/src/main/java/com/akash/newzz_compose/ui/common/Common.kt @@ -1,6 +1,7 @@ package com.akash.newzz_compose.ui.common import androidx.compose.Composable +import androidx.ui.core.Alignment import androidx.ui.core.ContentScale import androidx.ui.core.Modifier import androidx.ui.foundation.Box @@ -9,10 +10,8 @@ import androidx.ui.foundation.shape.corner.RoundedCornerShape import androidx.ui.graphics.Color import androidx.ui.graphics.Shape import androidx.ui.graphics.vector.VectorAsset -import androidx.ui.layout.Spacer -import androidx.ui.layout.fillMaxSize -import androidx.ui.layout.preferredHeight -import androidx.ui.layout.preferredWidth +import androidx.ui.layout.* +import androidx.ui.material.CircularProgressIndicator import androidx.ui.material.Surface import androidx.ui.res.vectorResource import androidx.ui.unit.Dp @@ -40,11 +39,11 @@ fun RemoteImage( modifier: Modifier, errorImage: VectorAsset = vectorResource(id = R.drawable.ic_newzz_error), contentScale: ContentScale = ContentScale.Crop, - shape : Shape = RoundedCornerShape(5.dp) + shape: Shape = RoundedCornerShape(5.dp) ) { Box( modifier = modifier - ){ + ) { if (url.isNullOrEmpty()) { Image( modifier = Modifier.fillMaxSize(), @@ -57,7 +56,12 @@ fun RemoteImage( ) { CoilImageWithCrossfade( data = url, - contentScale = contentScale + contentScale = contentScale, + loading = { + Stack(Modifier.fillMaxSize()) { + CircularProgressIndicator(Modifier.gravity(Alignment.Center)) + } + } ) } } diff --git a/app/src/main/java/com/akash/newzz_compose/ui/home/BodyContent.kt b/app/src/main/java/com/akash/newzz_compose/ui/home/BodyContent.kt index 0932eea..54ebcd9 100644 --- a/app/src/main/java/com/akash/newzz_compose/ui/home/BodyContent.kt +++ b/app/src/main/java/com/akash/newzz_compose/ui/home/BodyContent.kt @@ -21,7 +21,7 @@ import androidx.ui.unit.dp import com.akash.newzz_compose.Category import com.akash.newzz_compose.R import com.akash.newzz_compose.style.* -import com.akash.newzz_compose.ui.articleListPage.ArticleList +import com.akash.newzz_compose.ui.articlelist.ArticleList import com.akash.newzz_compose.viewmodel.NewzzViewModel @@ -96,7 +96,11 @@ fun TopAppBar(viewModel: NewzzViewModel) { } @Composable -fun ArticleStateWidget(state: State, isDark: State, onClick: () -> Unit) { +fun ArticleStateWidget( + state: State, + isDark: State, + onClick: () -> Unit +) { when { state.value.isLoading -> { Loading(isDark) @@ -145,21 +149,26 @@ fun Loading(isDark: State) { } @Composable -fun ErrorView(errorMessage: String, showRetry: Boolean, isDark: State, onClick: () -> Unit) { +fun ErrorView( + errorMessage: String, + showRetry: Boolean, + isDark: State, + onClick: () -> Unit +) { Column( verticalArrangement = Arrangement.Center, horizontalGravity = Alignment.CenterHorizontally ) { Text( text = errorMessage, - style = if(isDark.value) articleTitleStyle.copy(color = titleColorDark) else articleTitleStyle + style = if (isDark.value) articleTitleStyle.copy(color = titleColorDark) else articleTitleStyle ) if (showRetry) { TextButton(onClick = onClick) { Text( text = "Retry", style = TextStyle( - color = if(isDark.value) sourceTextColorDark else deepPurple + color = if (isDark.value) sourceTextColorDark else deepPurple ) ) } diff --git a/app/src/main/java/com/akash/newzz_compose/ui/home/BottomBar.kt b/app/src/main/java/com/akash/newzz_compose/ui/home/BottomBar.kt index 857b34e..b2fea34 100644 --- a/app/src/main/java/com/akash/newzz_compose/ui/home/BottomBar.kt +++ b/app/src/main/java/com/akash/newzz_compose/ui/home/BottomBar.kt @@ -74,7 +74,12 @@ fun BottomBar(viewModel: NewzzViewModel) { } @Composable -fun BottomNavItem(asset: Int, isDark: State, onClick: () -> Unit, isSelected: Boolean = false) { +fun BottomNavItem( + asset: Int, + isDark: State, + onClick: () -> Unit, + isSelected: Boolean = false +) { IconButton(onClick = onClick) { Icon( asset = vectorResource(id = asset), diff --git a/app/src/main/java/com/akash/newzz_compose/viewmodel/NewzzViewModel.kt b/app/src/main/java/com/akash/newzz_compose/viewmodel/NewzzViewModel.kt index 83f61ac..afe4ce4 100644 --- a/app/src/main/java/com/akash/newzz_compose/viewmodel/NewzzViewModel.kt +++ b/app/src/main/java/com/akash/newzz_compose/viewmodel/NewzzViewModel.kt @@ -19,8 +19,7 @@ class NewzzViewModel(private val repo: NewsRepository) : ViewModel() { private val viewModelScope = CoroutineScope(Dispatchers.Main) + job private val _pageNumber = MutableLiveData().apply { - value = - General + value = General } val pageNumber: LiveData = _pageNumber @@ -120,7 +119,7 @@ class NewzzViewModel(private val repo: NewsRepository) : ViewModel() { private suspend fun fetchBusinessArticles(category: String) { val state = businessState.value!! if (state.list == null || state.list.isEmpty()) { - withContext(Dispatchers.Main){ + withContext(Dispatchers.Main) { val articleState = ArticleState() _businessState.value = articleState } @@ -152,7 +151,7 @@ class NewzzViewModel(private val repo: NewsRepository) : ViewModel() { private suspend fun fetchTechArticles(category: String) { val state = techState.value!! if (state.list == null || state.list.isEmpty()) { - withContext(Dispatchers.Main){ + withContext(Dispatchers.Main) { val articleState = ArticleState() _techState.value = articleState } @@ -194,8 +193,8 @@ class NewzzViewModel(private val repo: NewsRepository) : ViewModel() { ) data class Error( - val errorMessage : String, - val showRetry : Boolean = true + val errorMessage: String, + val showRetry: Boolean = true ) companion object { diff --git a/build.gradle b/build.gradle index 5502686..576586d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.kotlin_version = "1.3.72" - ext.compose_version = "0.1.0-dev12" + ext.compose_version = "0.1.0-dev13" ext.coroutines_version = "1.3.6" ext.koin_version = "2.1.5" repositories { @@ -9,7 +9,7 @@ buildscript { jcenter() } dependencies { - classpath "com.android.tools.build:gradle:4.0.0-alpha09" + classpath "com.android.tools.build:gradle:4.0.0" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6b6c668..cb2dd23 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-rc-1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip