Skip to content

Commit

Permalink
Merge branch 'feature/implement-save-draft' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
geckour committed Aug 29, 2017
2 parents 117a2d6 + 89685a8 commit cdb7949
Show file tree
Hide file tree
Showing 10 changed files with 261 additions and 123 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.geckour.egret.api.model

import android.os.Parcelable
import com.google.gson.annotations.SerializedName

data class Attachment(
Expand Down
7 changes: 5 additions & 2 deletions app/src/main/java/com/geckour/egret/model/Draft.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import com.github.gfx.android.orma.annotation.Table
@Table
data class Draft(
@Setter("id") @PrimaryKey(autoincrement = true) val id: Long = -1L,
@Setter("tokenId") @Column var tokenId: Long = -1L,
@Setter("tokenId") @Column(indexed = true) var tokenId: Long = -1L,
@Setter("body") @Column var body: String = "",
@Setter("alertBody") @Column var alertBody: String = "",
@Setter("inReplyToId") @Column var inReplyToId: Long? = null,
@Setter("inReplyToName") @Column var inReplyToName: String? = null,
@Setter("attachments") @Column var attachments: Attachments,
@Setter("warning") @Column var warning: Boolean = false,
@Setter("sensitive") @Column var sensitive: Boolean = false,
@Setter("visibility") @Column var visibility: Int = MastodonService.Visibility.public.ordinal
@Setter("visibility") @Column var visibility: Int = MastodonService.Visibility.public.ordinal,
@Setter("createdAt") @Column(indexed = true) var createdAt: Long = System.currentTimeMillis()
) {
data class Attachments(
val value: List<Attachment> = ArrayList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ class MainActivity : BaseActivity(), ListDialogFragment.OnItemClickListener {
if (drawer.isDrawerOpen) {
drawer.closeDrawer()
} else {
(supportFragmentManager.fragments.lastOrNull { it.isVisible } as? OnBackPressedListener)?.let {
(supportFragmentManager.fragments.lastOrNull { it?.isVisible ?: false } as? OnBackPressedListener)?.let {
it.onBackPressedInMainActivity { if (it) super.onBackPressed() }
} ?: super.onBackPressed()
}
Expand Down
48 changes: 27 additions & 21 deletions app/src/main/java/com/geckour/egret/view/adapter/TimelineAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import io.reactivex.schedulers.Schedulers
import java.util.*
import kotlin.collections.ArrayList

class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootCallback? = null, val doFilter: Boolean = true) : RecyclerView.Adapter<TimelineAdapter.ViewHolder>() {
class TimelineAdapter(
val listener: Callbacks,
private val onAddTootListener: OnAddTootCallback? = null,
private val doFilter: Boolean = true): RecyclerView.Adapter<TimelineAdapter.ViewHolder>() {

companion object {
const val DEFAULT_ITEMS_LIMIT = 100
Expand Down Expand Up @@ -89,19 +92,19 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
content.mediaUrls.indices.forEach {
when (it) {
0 -> {
if (content.isSensitive ?: false) toggleMediaSpoiler(timelineBinding.mediaSpoilerWrap1, true)
if (content.isSensitive == true) toggleMediaSpoiler(timelineBinding.mediaSpoilerWrap1, true)
setupMedia(timelineBinding.media1, content.mediaPreviewUrls, content.mediaUrls, it)
}
1 -> {
if (content.isSensitive ?: false) toggleMediaSpoiler(timelineBinding.mediaSpoilerWrap2, true)
if (content.isSensitive == true) toggleMediaSpoiler(timelineBinding.mediaSpoilerWrap2, true)
setupMedia(timelineBinding.media2, content.mediaPreviewUrls, content.mediaUrls, it)
}
2 -> {
if (content.isSensitive ?: false) toggleMediaSpoiler(timelineBinding.mediaSpoilerWrap3, true)
if (content.isSensitive == true) toggleMediaSpoiler(timelineBinding.mediaSpoilerWrap3, true)
setupMedia(timelineBinding.media3, content.mediaPreviewUrls, content.mediaUrls, it)
}
3 -> {
if (content.isSensitive ?: false) toggleMediaSpoiler(timelineBinding.mediaSpoilerWrap4, true)
if (content.isSensitive == true) toggleMediaSpoiler(timelineBinding.mediaSpoilerWrap4, true)
setupMedia(timelineBinding.media4, content.mediaPreviewUrls, content.mediaUrls, it)
}
}
Expand Down Expand Up @@ -157,7 +160,7 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
else toggleStatus(ContentType.Notification, true)
}

fun initVisibility(type: ContentType) {
private fun initVisibility(type: ContentType) {
toggleAction(type, false)
toggleStatus(type, false)
initSpoiler(type)
Expand All @@ -166,6 +169,9 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
ContentType.Status -> {
timelineBinding.body.text = null

timelineBinding.actionLock.visibility = View.GONE
timelineBinding.lock.visibility = View.GONE

listOf(timelineBinding.media1, timelineBinding.media2, timelineBinding.media3, timelineBinding.media4)
.forEach {
it.apply {
Expand All @@ -184,6 +190,9 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
visibility = View.GONE
}

notificationBinding.actionLock.visibility = View.GONE
notificationBinding.lock.visibility = View.GONE

listOf(notificationBinding.media1, notificationBinding.media2, notificationBinding.media3, notificationBinding.media4)
.forEach {
it.apply {
Expand All @@ -198,7 +207,7 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
}
}

fun bindAction(contentType: ContentType, notificationType: Notification.NotificationType) {
private fun bindAction(contentType: ContentType, notificationType: Notification.NotificationType) {
when (contentType) {
ContentType.Status -> {
if (notificationType == Notification.NotificationType.reblog) {
Expand Down Expand Up @@ -232,7 +241,7 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
}
}

fun toggleAction(type: ContentType, show: Boolean) {
private fun toggleAction(type: ContentType, show: Boolean) {
when(type) {
ContentType.Status -> {
listOf(timelineBinding.indicateAction, timelineBinding.actionIcon, timelineBinding.actionBy, timelineBinding.actionName)
Expand All @@ -256,7 +265,7 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
}
}

fun toggleStatus(type: ContentType, show: Boolean) {
private fun toggleStatus(type: ContentType, show: Boolean) {
when(type) {
ContentType.Status -> {
listOf(
Expand Down Expand Up @@ -294,7 +303,7 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
}
}

fun initSpoiler(type: ContentType) {
private fun initSpoiler(type: ContentType) {
when(type) {
ContentType.Status -> {
timelineBinding.bodyAdditional.visibility = View.GONE
Expand All @@ -308,7 +317,7 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
}
}

fun toggleBodySpoiler(type: ContentType, show: Boolean) {
private fun toggleBodySpoiler(type: ContentType, show: Boolean) {
when(type) {
ContentType.Status -> {
timelineBinding.clearSpoiler.apply {
Expand Down Expand Up @@ -409,22 +418,22 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
popup.show()
}

fun toggleMediaSpoiler(view: View, show: Boolean) {
private fun toggleMediaSpoiler(view: View, show: Boolean) {
view.apply {
setOnClickListener { it.visibility = View.GONE }
visibility = if (show) View.VISIBLE else View.GONE
}
}

fun setupMedia(view: ImageView, previewUrls: List<String>, urls: List<String>, position: Int) {
private fun setupMedia(view: ImageView, previewUrls: List<String>, urls: List<String>, position: Int) {
view.apply {
visibility = View.VISIBLE
setOnClickListener { listener.onClickMedia(urls, position) }
}
Glide.with(view.context).load(previewUrls[position]).into(view)
}

fun reflectTreeStatus() {
private fun reflectTreeStatus() {
when (timelineBinding.status.treeStatus) {
TimelineContent.TimelineStatus.TreeStatus.None -> {
timelineBinding.treeLineUpper.visibility = View.GONE
Expand All @@ -446,9 +455,8 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
}
}

override fun getItemViewType(position: Int): Int {
return getContent(position).let { if (it.status != null) ContentType.Status.ordinal else if (it.notification != null) ContentType.Notification.ordinal else -1 }
}
override fun getItemViewType(position: Int): Int =
getContent(position).let { if (it.status != null) ContentType.Status.ordinal else if (it.notification != null) ContentType.Notification.ordinal else -1 }

override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
if (viewType == ContentType.Status.ordinal) {
Expand All @@ -468,9 +476,7 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
item.notification?.let { holder?.bindData(it) }
}

override fun getItemCount(): Int {
return contents.size
}
override fun getItemCount(): Int = contents.size

fun getContent(index: Int): TimelineContent = this.contents[index]

Expand Down Expand Up @@ -560,7 +566,7 @@ class TimelineAdapter(val listener: Callbacks, val onAddTootListener: OnAddTootC
}
}

fun shouldMute(content: TimelineContent): Single<Pair<TimelineContent, Boolean>> {
private fun shouldMute(content: TimelineContent): Single<Pair<TimelineContent, Boolean>> {
return Single.just(content)
.map {
val mute: Boolean = run {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import okhttp3.RequestBody
import java.io.File


class NewTootCreateFragment : BaseFragment(), MainActivity.OnBackPressedListener {
class NewTootCreateFragment : BaseFragment(), MainActivity.OnBackPressedListener, SelectDraftDialogFragment.OnSelectDraftItemListener {

lateinit private var binding: FragmentCreateNewTootBinding
private val postMediaReqs: ArrayList<Disposable> = ArrayList()
Expand All @@ -54,6 +54,8 @@ class NewTootCreateFragment : BaseFragment(), MainActivity.OnBackPressedListener
lateinit private var initialBody: String
lateinit private var initialAlertBody: String
private var isSuccessPost = false
private val drafts: ArrayList<Draft> = ArrayList()
private var draft: Draft? = null

companion object {
val TAG: String = this::class.java.simpleName
Expand Down Expand Up @@ -190,6 +192,23 @@ class NewTootCreateFragment : BaseFragment(), MainActivity.OnBackPressedListener

initialBody = binding.tootBody.text.toString()
initialAlertBody = binding.tootAlertBody.text.toString()

Common.getCurrentAccessToken()?.id?.let {
drafts.addAll(
OrmaProvider.db.relationOfDraft()
.tokenIdEq(it)
.orderByCreatedAtAsc()
)
}
binding.draft.apply {
if (drafts.isNotEmpty()) {
visibility = View.VISIBLE
setOnClickListener { onLoadDraft() }
} else {
visibility = View.INVISIBLE
setOnClickListener(null)
}
}
}

override fun onPause() {
Expand Down Expand Up @@ -236,6 +255,65 @@ class NewTootCreateFragment : BaseFragment(), MainActivity.OnBackPressedListener
} else callback(true)
}

override fun onSelect(draft: Draft) {
this.draft = draft
OrmaProvider.db.relationOfDraft()
.deleter()
.idEq(draft.id)
.executeAsSingle()
.map {
Common.getCurrentAccessToken()?.id?.let {
OrmaProvider.db.relationOfDraft()
.tokenIdEq(it)
.orderByCreatedAtAsc()
.toList()
} ?: arrayListOf()
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ drafts ->
this.drafts.apply {
clear()
addAll(drafts)
}
if (this.drafts.isEmpty()) binding.draft.apply {
visibility = View.INVISIBLE
setOnClickListener(null)
}
var account = ""
if (draft.inReplyToId != null && draft.inReplyToName != null) {
binding.replyTo.text = "reply to: ${draft.inReplyToName}"
binding.replyTo.visibility = View.VISIBLE
account = "${draft.inReplyToName} "
}
val body = "$account${draft.body}"
binding.tootBody.setText(body)
binding.tootBody.setSelection(body.length)
binding.tootAlertBody.setText(draft.alertBody)
this.attachments.apply {
clear()
addAll(draft.attachments.value)
}
Observable.fromIterable(this.attachments.mapIndexed { i, attachment -> Pair(i, attachment)})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ (i, attachment) ->
Glide.with(activity).load(attachment.previewImgUrl).into(
when (i) {
0 -> binding.media1
1 -> binding.media2
2 -> binding.media3
3 -> binding.media4
else -> throw IndexOutOfBoundsException("There are attachments over 4.")
}
)
}, Throwable::printStackTrace)
binding.switchCw.isChecked = draft.warning
binding.switchNsfw.isChecked = draft.sensitive
binding.spinnerVisibility.setSelection(draft.visibility)
}, Throwable::printStackTrace)
}

private fun postToot(body: String) {
if (body.isBlank()) {
Snackbar.make(binding.root, R.string.error_empty_toot, Snackbar.LENGTH_SHORT)
Expand All @@ -245,7 +323,7 @@ class NewTootCreateFragment : BaseFragment(), MainActivity.OnBackPressedListener
MastodonClient(Common.resetAuthInfo() ?: return)
.postNewToot(
body = body,
inReplyToId = if (binding.replyTo.visibility == View.VISIBLE) arguments.getLong(ARGS_KEY_REPLY_TO_STATUS_ID) else null,
inReplyToId = if (binding.replyTo.visibility == View.VISIBLE) draft?.inReplyToId ?: arguments.getLong(ARGS_KEY_REPLY_TO_STATUS_ID) else null,
mediaIds = if (attachments.size > 0) attachments.map { it.id } else null,
isSensitive = binding.switchNsfw.isChecked,
spoilerText = if (binding.switchCw.isChecked) binding.tootAlertBody.text.toString() else null,
Expand All @@ -270,16 +348,12 @@ class NewTootCreateFragment : BaseFragment(), MainActivity.OnBackPressedListener
tokenId = id,
body = binding.tootBody.text.toString(),
alertBody = binding.tootAlertBody.text.toString(),
inReplyToId = if (binding.replyTo.visibility == View.VISIBLE) arguments.getLong(ARGS_KEY_REPLY_TO_STATUS_ID) else null,
inReplyToId = if (binding.replyTo.visibility == View.VISIBLE) draft?.inReplyToId ?: arguments.getLong(ARGS_KEY_REPLY_TO_STATUS_ID) else null,
inReplyToName = if (binding.replyTo.visibility == View.VISIBLE) draft?.inReplyToName ?: arguments.getString(ARGS_KEY_REPLY_TO_ACCOUNT_NAME) else null,
attachments = Draft.Attachments(attachments),
warning = binding.switchCw.isChecked,
sensitive = binding.switchNsfw.isChecked,
visibility = when (binding.spinnerVisibility.selectedItemPosition) {
0 -> MastodonService.Visibility.public.ordinal
1 -> MastodonService.Visibility.unlisted.ordinal
2 -> MastodonService.Visibility.private.ordinal
3 -> MastodonService.Visibility.direct.ordinal
else -> -1
}
visibility = binding.spinnerVisibility.selectedItemPosition
)
}
.subscribeOn(Schedulers.io())
Expand Down Expand Up @@ -330,6 +404,14 @@ class NewTootCreateFragment : BaseFragment(), MainActivity.OnBackPressedListener
}
}

private fun onLoadDraft() {
SelectDraftDialogFragment.newInstance(drafts)
.apply {
setTargetFragment(this@NewTootCreateFragment, 0)
}
.show(activity.supportFragmentManager, SelectDraftDialogFragment.TAG)
}

private fun pickMedia() {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Expand Down
Loading

0 comments on commit cdb7949

Please sign in to comment.