Skip to content

Commit

Permalink
Merge branch 'feature/writing_suggestions' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
MrHadiSatrio authored Dec 31, 2024
2 parents cf2fc1a + 51e9ad1 commit 16181a9
Show file tree
Hide file tree
Showing 23 changed files with 453 additions and 21 deletions.
4 changes: 4 additions & 0 deletions app-android-journal3/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
</intent-filter>
</activity>

<activity
android:name=".moment.ViewWritingSuggestionsActivity"
android:theme="@style/Theme.Journal3.Translucent" />

<activity
android:name=".moment.EditAMomentActivity"
android:theme="@style/Theme.Journal3.NoActionBar" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import android.content.Intent
import com.hadisatrio.apps.android.journal3.geography.SelectAPlaceActivity
import com.hadisatrio.apps.android.journal3.moment.DeleteAMomentActivity
import com.hadisatrio.apps.android.journal3.moment.EditAMomentActivity
import com.hadisatrio.apps.android.journal3.moment.ViewWritingSuggestionsActivity
import com.hadisatrio.libs.android.foundation.activity.CurrentActivity
import com.hadisatrio.libs.kotlin.foundation.event.Event
import com.hadisatrio.libs.kotlin.foundation.event.EventSink
Expand All @@ -38,6 +39,7 @@ class ActivityRoutingEventSink(
when (identifier) {
"view_reflections" -> activity.startViewReflectionsActivity()
"view_story" -> activity.startViewStoryActivity()
"view_writing_suggestions" -> activity.startViewWritingSuggestionsActivity()
"add_moment" -> activity.startAddAMomentActivity(event)
"edit_moment" -> activity.startEditAMomentActivity(event)
"delete_moment" -> activity.startDeleteAMomentActivity(event)
Expand All @@ -57,6 +59,11 @@ class ActivityRoutingEventSink(
startActivity(intent)
}

private fun Activity.startViewWritingSuggestionsActivity() {
val intent = Intent(this, ViewWritingSuggestionsActivity::class.java)
startActivity(intent)
}

private fun Activity.startAddAMomentActivity(event: SelectionEvent) {
val intent = Intent(this, EditAMomentActivity::class.java)
intent.putExtra("story_id", event["story_id"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ abstract class Journal3Application : Application() {
abstract val speed: Speed
abstract val places: Places
abstract val story: Story
abstract val notableStory: Story
abstract val reflections: Stories
abstract val modalPresenter: Presenter<Modal>
abstract val currentActivity: CurrentActivity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import com.hadisatrio.apps.kotlin.journal3.sentiment.SentimentAnalyst
import com.hadisatrio.apps.kotlin.journal3.sentiment.VeryPositiveSentimentRange
import com.hadisatrio.apps.kotlin.journal3.story.InitDeferringStories
import com.hadisatrio.apps.kotlin.journal3.story.MomentfulStories
import com.hadisatrio.apps.kotlin.journal3.story.NotabilityFilteringStory
import com.hadisatrio.apps.kotlin.journal3.story.Reflection
import com.hadisatrio.apps.kotlin.journal3.story.Stories
import com.hadisatrio.apps.kotlin.journal3.story.Story
Expand Down Expand Up @@ -111,6 +112,10 @@ class RealJournal3Application : Journal3Application() {
)
}

override val notableStory: Story by lazy {
NotabilityFilteringStory(notable = true, story)
}

private val memorables by lazy {
MergedMemorables(
FilesystemMemorablePlaces(
Expand Down Expand Up @@ -145,7 +150,7 @@ class RealJournal3Application : Journal3Application() {
origin = VicinityMoments(
coordinates = coordinates,
distanceLimitInM = 100.0,
origin = story.moments
origin = notableStory.moments
)
)
)
Expand All @@ -162,7 +167,7 @@ class RealJournal3Application : Journal3Application() {
),
origin = SentimentRangedMoments(
sentimentRange = PositiveishSentimentRange,
origin = story.moments
origin = notableStory.moments
)
)
)
Expand All @@ -176,7 +181,7 @@ class RealJournal3Application : Journal3Application() {
origin = OrderRandomizingMoments(
origin = SentimentRangedMoments(
sentimentRange = VeryPositiveSentimentRange,
origin = story.moments
origin = notableStory.moments
)
)
)
Expand All @@ -189,7 +194,7 @@ class RealJournal3Application : Journal3Application() {
origin = OrderRandomizingMoments(
origin = SentimentRangedMoments(
sentimentRange = NegativeishSentimentRange,
origin = story.moments
origin = notableStory.moments
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class RootActivity : AppCompatActivity() {
),
ViewClickEventSource(
view = findViewById(R.id.add_button),
eventFactory = { SelectionEvent("action", "add_moment") }
eventFactory = { SelectionEvent("action", "view_writing_suggestions") }
),
NavigationBarSelectionEventSource(
view = bottomBar,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import com.hadisatrio.apps.android.journal3.R
import com.hadisatrio.apps.android.journal3.journal3Application
import com.hadisatrio.apps.kotlin.journal3.geography.SelectAPlaceUseCase
import com.hadisatrio.libs.android.dimensions.dp
import com.hadisatrio.libs.android.foundation.activity.ActivityCompletionEventSink
import com.hadisatrio.libs.android.foundation.activity.ActivityFinishingEventSink
import com.hadisatrio.libs.android.foundation.activity.ActivityResultSettingEventSink
import com.hadisatrio.libs.android.foundation.lifecycle.LifecycleTriggeredEventSource
import com.hadisatrio.libs.android.foundation.presentation.ExecutorDispatchingPresenter
Expand Down Expand Up @@ -116,7 +116,7 @@ class SelectAPlaceActivity : AppCompatActivity() {
values
}
),
ActivityCompletionEventSink(this)
ActivityFinishingEventSink(this)
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import androidx.appcompat.app.AppCompatActivity
import com.benasher44.uuid.uuidFrom
import com.hadisatrio.apps.android.journal3.journal3Application
import com.hadisatrio.apps.kotlin.journal3.moment.DeleteMomentUseCase
import com.hadisatrio.libs.android.foundation.activity.ActivityCompletionEventSink
import com.hadisatrio.libs.android.foundation.activity.ActivityFinishingEventSink
import com.hadisatrio.libs.android.foundation.presentation.ExecutorDispatchingPresenter
import com.hadisatrio.libs.kotlin.foundation.event.EventSinks
import com.hadisatrio.libs.kotlin.foundation.modal.Modal
Expand All @@ -48,7 +48,7 @@ class DeleteAMomentActivity : AppCompatActivity() {
eventSink = journal3Application.eventSinkDecor.apply(
EventSinks(
journal3Application.globalEventSink,
ActivityCompletionEventSink(this)
ActivityFinishingEventSink(this)
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import com.hadisatrio.apps.kotlin.journal3.moment.Moment
import com.hadisatrio.apps.kotlin.journal3.moment.SentimentAnalyzingMoment
import com.hadisatrio.apps.kotlin.journal3.moment.UpdateDeferringMoment
import com.hadisatrio.apps.kotlin.journal3.story.EditableMomentInStory
import com.hadisatrio.libs.android.foundation.activity.ActivityCompletionEventSink
import com.hadisatrio.libs.android.foundation.activity.ActivityFinishingEventSink
import com.hadisatrio.libs.android.foundation.lifecycle.LifecycleTriggeredEventSource
import com.hadisatrio.libs.android.foundation.material.SliderFloatPresenter
import com.hadisatrio.libs.android.foundation.material.SliderSelectionEventSource
Expand Down Expand Up @@ -179,7 +179,7 @@ class EditAMomentActivity : AppCompatActivity() {
journal3Application.eventSinkDecor.apply(
EventSinks(
journal3Application.globalEventSink,
ActivityCompletionEventSink(this)
ActivityFinishingEventSink(this)
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* Copyright (C) 2022 Hadi Satrio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.hadisatrio.apps.android.journal3.moment

import android.graphics.Rect
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.grzegorzojdana.spacingitemdecoration.Spacing
import com.grzegorzojdana.spacingitemdecoration.SpacingItemDecoration
import com.hadisatrio.apps.android.journal3.R
import com.hadisatrio.apps.android.journal3.journal3Application
import com.hadisatrio.apps.android.journal3.sentiment.TextViewColorSentimentPresenter
import com.hadisatrio.apps.kotlin.journal3.event.RefreshRequestEvent
import com.hadisatrio.apps.kotlin.journal3.moment.Moment
import com.hadisatrio.apps.kotlin.journal3.story.NotabilityFilteringStory
import com.hadisatrio.apps.kotlin.journal3.story.ShowStoryUseCase
import com.hadisatrio.apps.kotlin.journal3.story.Story
import com.hadisatrio.apps.kotlin.journal3.story.cache.CachingStoryPresenter
import com.hadisatrio.libs.android.dimensions.dp
import com.hadisatrio.libs.android.foundation.activity.ActivityFinishingEventSink
import com.hadisatrio.libs.android.foundation.lifecycle.LifecycleTriggeredEventSource
import com.hadisatrio.libs.android.foundation.presentation.ExecutorDispatchingPresenter
import com.hadisatrio.libs.android.foundation.widget.ViewClickEventSource
import com.hadisatrio.libs.android.foundation.widget.recyclerview.ListViewPresenter
import com.hadisatrio.libs.android.foundation.widget.recyclerview.RecyclerViewItemSelectionEventSource
import com.hadisatrio.libs.android.foundation.widget.recyclerview.ViewFactory
import com.hadisatrio.libs.kotlin.foundation.UseCase
import com.hadisatrio.libs.kotlin.foundation.event.ActionSelectionEventPredicate
import com.hadisatrio.libs.kotlin.foundation.event.CancellationEvent
import com.hadisatrio.libs.kotlin.foundation.event.EventSink
import com.hadisatrio.libs.kotlin.foundation.event.EventSinks
import com.hadisatrio.libs.kotlin.foundation.event.EventSource
import com.hadisatrio.libs.kotlin.foundation.event.EventSources
import com.hadisatrio.libs.kotlin.foundation.event.SelectionEvent
import com.hadisatrio.libs.kotlin.foundation.event.SkippingEventSource
import com.hadisatrio.libs.kotlin.foundation.presentation.AdaptingPresenter
import com.hadisatrio.libs.kotlin.foundation.presentation.Presenter

class ViewWritingSuggestionsActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Fragment().show(supportFragmentManager, FRAGMENT_TAG)
}

class Fragment : BottomSheetDialogFragment() {

private val presenter: Presenter<Story> by lazy {
val momentsViewFactory = ViewFactory { parent, _ ->
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.view_moment_horz_card, parent, false)
val width = RecyclerView.LayoutParams.MATCH_PARENT
val height = RecyclerView.LayoutParams.WRAP_CONTENT
val sentimentPresenter = TextViewColorSentimentPresenter(view.findViewById(R.id.sentiment_indicator))
view.layoutParams = RecyclerView.LayoutParams(width, height)
view.setTag(R.id.presenter_view_tag, sentimentPresenter)
view
}
val momentsPresenter = AdaptingPresenter<Story, Iterable<Moment>>(
adapter = { story -> story.moments },
origin = ListViewPresenter(
recyclerView = requireView().findViewById(R.id.moments_list),
orientation = RecyclerView.VERTICAL,
viewFactory = momentsViewFactory,
viewRenderer = MomentCardViewRenderer,
differ = MomentItemDiffer,
backgroundExecutor = journal3Application.backgroundExecutor
)
)

journal3Application.presenterDecor<Story>().apply(
CachingStoryPresenter(
origin = ExecutorDispatchingPresenter(
executor = journal3Application.foregroundExecutor,
origin = momentsPresenter
)
)
)
}

private val eventSource: EventSource by lazy {
journal3Application.eventSourceDecor.apply(
EventSources(
journal3Application.globalEventSource,
SkippingEventSource(
count = 1,
origin = LifecycleTriggeredEventSource(
lifecycleOwner = this,
lifecycleEvent = Lifecycle.Event.ON_START,
eventFactory = { RefreshRequestEvent("lifecycle") }
)
),
LifecycleTriggeredEventSource(
lifecycleOwner = this,
lifecycleEvent = Lifecycle.Event.ON_DESTROY,
eventFactory = { CancellationEvent("system") }
),
ViewClickEventSource(
view = requireView().findViewById(R.id.add_button),
eventFactory = { SelectionEvent("action", "add_moment") }
),
RecyclerViewItemSelectionEventSource(
recyclerView = requireView().findViewById(R.id.moments_list)
)
)
)
}

private val eventSink: EventSink by lazy {
journal3Application.eventSinkDecor.apply(
EventSinks(
journal3Application.globalEventSink,
ActivityFinishingEventSink(
activity = requireActivity(),
additionalPredicate = ActionSelectionEventPredicate("edit_moment", "add_moment")
)
)
)
}

private val useCase: UseCase by lazy {
journal3Application.useCaseDecor.apply(
ShowStoryUseCase(
story = NotabilityFilteringStory(notable = false, journal3Application.story),
presenter = presenter,
eventSource = eventSource,
eventSink = eventSink
)
)
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_view_writing_suggestions, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setupViews()
useCase()
}

private fun setupViews() {
requireView().findViewById<RecyclerView>(R.id.moments_list).addItemDecoration(
SpacingItemDecoration(
Spacing(
edges = Rect(0.dp, 0.dp, 0.dp, 0.dp),
horizontal = 0.dp,
vertical = 8.dp
)
)
)
}
}

companion object {
private val FRAGMENT_TAG = "${ViewWritingSuggestionsActivity::class.simpleName}Fragment"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import com.hadisatrio.apps.android.journal3.journal3Application
import com.hadisatrio.apps.kotlin.journal3.story.ShowStoriesUseCase
import com.hadisatrio.apps.kotlin.journal3.story.Stories
import com.hadisatrio.libs.android.dimensions.dp
import com.hadisatrio.libs.android.foundation.activity.ActivityCompletionEventSink
import com.hadisatrio.libs.android.foundation.activity.ActivityFinishingEventSink
import com.hadisatrio.libs.kotlin.foundation.UseCase
import com.hadisatrio.libs.kotlin.foundation.event.EventSink
import com.hadisatrio.libs.kotlin.foundation.event.EventSinks
Expand All @@ -54,7 +54,7 @@ abstract class StoriesListFragment : Fragment() {
journal3Application.eventSinkDecor.apply(
EventSinks(
journal3Application.globalEventSink,
ActivityCompletionEventSink(requireActivity())
ActivityFinishingEventSink(requireActivity())
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import com.hadisatrio.apps.kotlin.journal3.story.ShowStoryUseCase
import com.hadisatrio.apps.kotlin.journal3.story.Story
import com.hadisatrio.apps.kotlin.journal3.story.cache.CachingStoryPresenter
import com.hadisatrio.libs.android.dimensions.dp
import com.hadisatrio.libs.android.foundation.activity.ActivityCompletionEventSink
import com.hadisatrio.libs.android.foundation.activity.ActivityFinishingEventSink
import com.hadisatrio.libs.android.foundation.lifecycle.LifecycleTriggeredEventSource
import com.hadisatrio.libs.android.foundation.presentation.ExecutorDispatchingPresenter
import com.hadisatrio.libs.android.foundation.widget.recyclerview.ListViewPresenter
Expand Down Expand Up @@ -117,15 +117,15 @@ class ViewStoryFragment : Fragment() {
journal3Application.eventSinkDecor.apply(
EventSinks(
journal3Application.globalEventSink,
ActivityCompletionEventSink(requireActivity())
ActivityFinishingEventSink(requireActivity())
)
)
}

private val useCase: UseCase by lazy {
journal3Application.useCaseDecor.apply(
ShowStoryUseCase(
story = journal3Application.story,
story = journal3Application.notableStory,
presenter = presenter,
eventSource = eventSource,
eventSink = eventSink
Expand Down
Loading

0 comments on commit 16181a9

Please sign in to comment.