Skip to content

Commit

Permalink
Merge branch 'release/v0.9.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Vasilchenko committed Mar 5, 2018
2 parents 8b86cfc + 277de3f commit 6c06171
Show file tree
Hide file tree
Showing 46 changed files with 934 additions and 141 deletions.
4 changes: 4 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,8 @@ dependencies {
testImplementation developmentDependencies.leakCanaryNoOp
}

configurations.all() {
resolutionStrategy.force "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}

apply plugin: 'com.google.gms.google-services'
10 changes: 9 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@

<activity
android:name=".presentation.features.imagedisplay.ImageDisplayActivity"
android:label="@string/app_name"
android:parentActivityName=".presentation.features.navigation.MainActivity"
android:theme="@style/AppTheme.DarkBackground">
<meta-data
Expand Down Expand Up @@ -112,6 +111,15 @@
android:value=".presentation.features.navigation.MainActivity" />
</activity>

<activity
android:name=".presentation.features.gallery.TopicGalleryActivity"
android:parentActivityName=".presentation.features.navigation.MainActivity"
android:theme="@style/AppTheme.DarkBackground">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".presentation.features.navigation.MainActivity" />
</activity>

<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.sedsoftware.yaptalker"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.sedsoftware.yaptalker.di.modules.contribution

import com.sedsoftware.yaptalker.di.scopes.ActivityScope
import com.sedsoftware.yaptalker.presentation.features.gallery.TopicGalleryActivity
import com.sedsoftware.yaptalker.presentation.features.gallery.di.TopicGalleryActivityModule
import com.sedsoftware.yaptalker.presentation.features.gifdisplay.GifDisplayActivity
import com.sedsoftware.yaptalker.presentation.features.gifdisplay.di.GifDisplayActivityModule
import com.sedsoftware.yaptalker.presentation.features.imagedisplay.ImageDisplayActivity
Expand Down Expand Up @@ -37,4 +39,8 @@ interface ActivityContributionModule {
@ActivityScope
@ContributesAndroidInjector(modules = [(GifDisplayActivityModule::class)])
fun gifActivityInjector(): GifDisplayActivity

@ActivityScope
@ContributesAndroidInjector(modules = [(TopicGalleryActivityModule::class)])
fun galleryActivityInjector(): TopicGalleryActivity
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import com.arellomobile.mvp.viewstate.strategy.AddToEndSingleStrategy
import com.arellomobile.mvp.viewstate.strategy.SkipStrategy
import com.arellomobile.mvp.viewstate.strategy.StateStrategyType

@StateStrategyType(AddToEndSingleStrategy::class)
@StateStrategyType(SkipStrategy::class)
interface BaseView : MvpView {

@StateStrategyType(SkipStrategy::class)
fun showErrorMessage(message: String)

@StateStrategyType(value = AddToEndSingleStrategy::class, tag = "LoadingIndicator")
fun showLoadingIndicator() {
// Default empty implementation
}

@StateStrategyType(value = AddToEndSingleStrategy::class, tag = "LoadingIndicator")
fun hideLoadingIndicator() {
// Default empty implementation
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ class PresenterLifecycle {
}

@Retention(AnnotationRetention.SOURCE)
@IntDef(CREATE, DESTROY)
@IntDef(CREATE, ATTACH_VIEW, DETACH_VIEW, DESTROY)
annotation class Event
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ object NavigationScreen {
const val INCUBATOR_SCREEN = "INCUBATOR_SCREEN"
const val SEARCH_FORM = "SEARCH_FORM"
const val SEARCH_RESULTS = "SEARCH_RESULTS"
const val TOPIC_GALLERY = "TOPIC_GALLERY"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sedsoftware.yaptalker.presentation.extensions

import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView

fun RecyclerView.visibleItemPosition(): Int {
val layoutManager = this.layoutManager as? LinearLayoutManager
return layoutManager?.findFirstVisibleItemPosition() ?: -1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package com.sedsoftware.yaptalker.presentation.features.gallery

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.PagerSnapHelper
import android.view.Menu
import android.view.MenuItem
import com.arellomobile.mvp.presenter.InjectPresenter
import com.arellomobile.mvp.presenter.ProvidePresenter
import com.sedsoftware.yaptalker.R
import com.sedsoftware.yaptalker.commons.annotation.LayoutResource
import com.sedsoftware.yaptalker.presentation.base.BaseActivity
import com.sedsoftware.yaptalker.presentation.extensions.stringRes
import com.sedsoftware.yaptalker.presentation.extensions.toastError
import com.sedsoftware.yaptalker.presentation.extensions.toastSuccess
import com.sedsoftware.yaptalker.presentation.extensions.visibleItemPosition
import com.sedsoftware.yaptalker.presentation.features.gallery.adapter.TopicGalleryAdapter
import com.sedsoftware.yaptalker.presentation.features.gallery.adapter.TopicGalleryLoadMoreClickListener
import com.sedsoftware.yaptalker.presentation.model.YapEntity
import com.sedsoftware.yaptalker.presentation.model.base.SinglePostGalleryImageModel
import kotlinx.android.synthetic.main.activity_topic_gallery.topic_gallery
import kotlinx.android.synthetic.main.include_main_appbar_transparent.toolbar
import java.util.Locale
import javax.inject.Inject

@LayoutResource(R.layout.activity_topic_gallery)
class TopicGalleryActivity : BaseActivity(), TopicGalleryView, TopicGalleryLoadMoreClickListener {

companion object {
fun getIntent(ctx: Context, triple: Triple<Int, Int, Int>): Intent {
val intent = Intent(ctx, TopicGalleryActivity::class.java)
intent.putExtra(FORUM_ID_KEY, triple.first)
intent.putExtra(TOPIC_ID_KEY, triple.second)
intent.putExtra(CURRENT_PAGE_KEY, triple.third)
return intent
}

private const val FORUM_ID_KEY = "FORUM_ID_KEY"
private const val TOPIC_ID_KEY = "TOPIC_ID_KEY"
private const val CURRENT_PAGE_KEY = "CURRENT_PAGE_KEY"
private const val STORAGE_WRITE_PERMISSION = 0
}

private val titleTemplate: String by lazy {
stringRes(R.string.navigation_gallery_page)
}

@Inject
lateinit var galleryAdapter: TopicGalleryAdapter

@Inject
@InjectPresenter
lateinit var presenter: TopicGalleryPresenter

@ProvidePresenter
fun provideGalleryPresenter() = presenter

private val forumId: Int by lazy {
intent.getIntExtra(FORUM_ID_KEY, 0)
}

private val topicId: Int by lazy {
intent.getIntExtra(TOPIC_ID_KEY, 0)
}

private val currentPage: Int by lazy {
intent.getIntExtra(CURRENT_PAGE_KEY, 0)
}

private var savingImageUrl = ""

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

setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)

with(topic_gallery) {
val linearLayout = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
layoutManager = linearLayout
adapter = galleryAdapter
setHasFixedSize(true)
}

val snapHelper = PagerSnapHelper()
snapHelper.attachToRecyclerView(topic_gallery)

presenter.loadTopicGallery(forumId, topicId, currentPage)
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_image_display, menu)
return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
val itemPosition = topic_gallery.visibleItemPosition()

if (itemPosition == -1) {
return false
}

val imageUrl = galleryAdapter.items[itemPosition]

return when (item.itemId) {
R.id.action_share -> {
presenter.shareImage(imageUrl.url)
true
}
R.id.action_save -> {
checkPermissionAndSaveImage(imageUrl.url)
true
}
else -> super.onOptionsItemSelected(item)
}
}

override fun showErrorMessage(message: String) {
toastError(message)
}

override fun appendImages(images: List<YapEntity>) {
galleryAdapter.addList(images.map { it as SinglePostGalleryImageModel })
}

override fun updateCurrentUiState(title: String) {
supportActionBar?.title = String.format(Locale.getDefault(), titleTemplate, title)
}

override fun scrollToFirstNewImage(newImagesOffset: Int) {
topic_gallery.smoothScrollToPosition( galleryAdapter.itemCount - newImagesOffset)
}

override fun lastPageReached() {
galleryAdapter.isLastPageVisible = true
}

override fun fileSavedMessage(filepath: String) {
String.format(Locale.getDefault(), stringRes(R.string.msg_file_saved), filepath).apply {
toastSuccess(this)
}
}

override fun fileNotSavedMessage() {
toastError(stringRes(R.string.msg_file_not_saved))
}

override fun onLoadMoreClicked() {
presenter.loadMoreImages()
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
when (requestCode) {
STORAGE_WRITE_PERMISSION -> {
presenter.saveImage(savingImageUrl)
}
}
}

private fun checkPermissionAndSaveImage(imageUrl: String) {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED) {
savingImageUrl = imageUrl
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
STORAGE_WRITE_PERMISSION
)
} else {
presenter.saveImage(imageUrl)
}
}
}
Loading

0 comments on commit 6c06171

Please sign in to comment.