From c30deed5fc4283ec75b93c2ce62b897ff3a03639 Mon Sep 17 00:00:00 2001 From: Victor Rattis Date: Thu, 10 Oct 2019 19:03:42 -0300 Subject: [PATCH] [#172] Redesign List&Notes Screen draft... --- app/build.gradle | 31 +- app/src/main/AndroidManifest.xml | 2 +- .../app/StickySessionApplication.java | 17 +- .../repository/NoteRemoteRepository.java | 1 + .../domain/interactor/AddNote.java | 5 + .../domain/model/ISessionDetail.java | 10 + .../stickysessions/domain/model/Session.java | 23 +- .../injectors/components/SessionComponent.kt | 4 +- .../components/TopicNotesViewComponent.java | 37 ++ .../modules/NoteTopicPresenterModule.java | 22 ++ .../modules/SessionPresenterModule.java | 11 +- .../navigation/wrapper/ViewStarter.java | 4 +- .../list/ListSessionsPresenter.java | 2 +- .../presentation/lobby/LobbyPresenter.java | 4 +- .../presentation/notes/INoteTopicDetail.kt | 7 + .../presentation/notes/NoteTopicDetail.kt | 10 + .../presentation/notes/NotesContract.kt | 20 + .../presentation/notes/NotesPresenter.kt | 82 +++++ .../presentation/session/SessionContract.java | 37 -- .../presentation/session/SessionContract.kt | 22 ++ .../session/SessionPresenter.java | 182 ---------- .../presentation/session/SessionPresenter.kt | 91 +++++ .../ui/adapters/NoteAdapter.java | 157 -------- .../stickysessions/ui/notes/NotesActivity.kt | 152 ++++++++ .../ui/notes/adapters/NoteAdapter.kt | 49 +++ .../ui/notes/adapters/NotesByNotesAdapter.kt | 26 ++ .../custom/ItemAnimator.java | 2 +- .../custom/NoteGridLayoutManager.java | 3 +- .../custom/SquaredConstraintLayout.java | 2 +- .../ui/notes/holder/NoteViewHolder.kt | 27 ++ .../ui/notes/holder/NotesViewHolder.kt | 115 ++++++ .../ui/session/SessionActivity.java | 343 ------------------ app/src/main/res/layout/activity_session.xml | 32 +- app/src/main/res/layout/item_note.xml | 49 +++ app/src/main/res/layout/item_topic_notes.xml | 56 +++ app/src/main/res/layout/note_element.xml | 4 +- app/src/main/res/layout/toolbar_session.xml | 6 +- app/src/main/res/menu/session_menu.xml | 12 +- app/src/main/res/values/dimens.xml | 1 + app/src/main/res/values/styles.xml | 4 + .../navigation/ViewStarterTest.kt | 7 +- .../session/SessionPresenterTest.kt | 10 +- 42 files changed, 874 insertions(+), 807 deletions(-) create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/model/ISessionDetail.java create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/components/TopicNotesViewComponent.java create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/NoteTopicPresenterModule.java create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/INoteTopicDetail.kt create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NoteTopicDetail.kt create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NotesContract.kt create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NotesPresenter.kt delete mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionContract.java create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionContract.kt delete mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionPresenter.java create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionPresenter.kt delete mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/adapters/NoteAdapter.java create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/NotesActivity.kt create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/adapters/NoteAdapter.kt create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/adapters/NotesByNotesAdapter.kt rename app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/{session => notes}/custom/ItemAnimator.java (98%) rename app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/{session => notes}/custom/NoteGridLayoutManager.java (86%) rename app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/{session => notes}/custom/SquaredConstraintLayout.java (91%) create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/holder/NoteViewHolder.kt create mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/holder/NotesViewHolder.kt delete mode 100644 app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/SessionActivity.java create mode 100644 app/src/main/res/layout/item_note.xml create mode 100644 app/src/main/res/layout/item_topic_notes.xml diff --git a/app/build.gradle b/app/build.gradle index 9bf0e28f..6df9f70c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -54,13 +54,13 @@ android { flavorDimensions "server" productFlavors { - prod { - dimension "server" - ext { - url = "http://35.237.70.49:3000" - } - resValue "string", "app_name", "Sticky Sessions" - } +// prod { +// dimension "server" +// ext { +// url = "http://35.237.70.49:3000" +// } +// resValue "string", "app_name", "Sticky Sessions" +// } stag { dimension "server" applicationId = "${packageId}.stag" @@ -69,19 +69,20 @@ android { } resValue "string", "app_name", "Sticky Sessions (Staging)" } - local { - dimension "server" - applicationId = "${packageId}.local" - ext { - url = "http://localhost:3000" - } - resValue "string", "app_name", "Sticky Sessions (Local)" - } +// local { +// dimension "server" +// applicationId = "${packageId}.local" +// ext { +// url = "http://localhost:3000" +// } +// resValue "string", "app_name", "Sticky Sessions (Local)" +// } applicationVariants.all { variant -> def flavors = variant.productFlavors // flavorDimensions "server" -> 0 def server = flavors[0] variant.buildConfigField "String", "URL", "\"${server[url.name]}\"" + } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 87ef07a0..931df72e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,7 +39,7 @@ android:name=".ui.meeting.MeetingActivity" android:screenOrientation="${orientation}" /> diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/app/StickySessionApplication.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/app/StickySessionApplication.java index 774b350a..44d7fd85 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/app/StickySessionApplication.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/app/StickySessionApplication.java @@ -7,12 +7,14 @@ import br.org.cesar.discordtime.stickysessions.injectors.components.DaggerLoginComponent; import br.org.cesar.discordtime.stickysessions.injectors.components.DaggerMeetingComponent; import br.org.cesar.discordtime.stickysessions.injectors.components.DaggerSessionComponent; +import br.org.cesar.discordtime.stickysessions.injectors.components.DaggerTopicNotesViewComponent; import br.org.cesar.discordtime.stickysessions.injectors.modules.ContextModule; +import br.org.cesar.discordtime.stickysessions.ui.notes.holder.NotesViewHolder; import br.org.cesar.discordtime.stickysessions.ui.list.ListSessionsActivity; import br.org.cesar.discordtime.stickysessions.ui.lobby.LobbyActivity; import br.org.cesar.discordtime.stickysessions.ui.login.LoginActivity; import br.org.cesar.discordtime.stickysessions.ui.meeting.MeetingActivity; -import br.org.cesar.discordtime.stickysessions.ui.session.SessionActivity; +import br.org.cesar.discordtime.stickysessions.ui.notes.NotesActivity; public class StickySessionApplication extends Application { @@ -21,6 +23,8 @@ public class StickySessionApplication extends Application { protected DaggerSessionComponent.Builder mSessionComponentBuilder; protected DaggerListSessionComponent.Builder mSessionListBuilder; protected DaggerMeetingComponent.Builder mMeetingComponentBuilder; + protected DaggerTopicNotesViewComponent.Builder mTopicNotesViewBuilder; + @Override public void onCreate() { @@ -30,6 +34,7 @@ public void onCreate() { configureSessionInjectorBuilder(); configureSessionListInjectorBuilder(); configureMeetingInjectorBuilder(); + configureTopicNotesViewBuilder(); } protected void configureLoginInjectorBuilder() { @@ -56,6 +61,11 @@ protected void configureMeetingInjectorBuilder() { .contextModule(new ContextModule(getApplicationContext())); } + protected void configureTopicNotesViewBuilder() { + mTopicNotesViewBuilder = DaggerTopicNotesViewComponent.builder() + .contextModule(new ContextModule(getApplicationContext())); + } + public void inject(LoginActivity activity) { mLoginComponentBuilder.build().inject(activity); } @@ -64,7 +74,7 @@ public void inject(LobbyActivity activity) { mLobbyComponentBuilder.build().inject(activity); } - public void inject(SessionActivity activity) { + public void inject(NotesActivity activity) { mSessionComponentBuilder.build().inject(activity); } @@ -76,4 +86,7 @@ public void inject(MeetingActivity activity) { mMeetingComponentBuilder.build().inject(activity); } + public void inject(final NotesViewHolder topicNotesView) { + mTopicNotesViewBuilder.build().inject(topicNotesView); + } } diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/data/remote/repository/NoteRemoteRepository.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/data/remote/repository/NoteRemoteRepository.java index 5c9934b1..73fcb181 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/data/remote/repository/NoteRemoteRepository.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/data/remote/repository/NoteRemoteRepository.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import br.org.cesar.discordtime.stickysessions.BuildConfig; import br.org.cesar.discordtime.stickysessions.data.remote.model.NoteRemote; import br.org.cesar.discordtime.stickysessions.data.remote.service.NoteService; import br.org.cesar.discordtime.stickysessions.data.repository.mapper.Mapper; diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/interactor/AddNote.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/interactor/AddNote.java index d0e3ac22..793f0275 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/interactor/AddNote.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/interactor/AddNote.java @@ -1,5 +1,9 @@ package br.org.cesar.discordtime.stickysessions.domain.interactor; +import android.util.Log; + +import javax.inject.Singleton; + import br.org.cesar.discordtime.stickysessions.domain.model.Note; import br.org.cesar.discordtime.stickysessions.domain.repository.NoteRepository; import br.org.cesar.discordtime.stickysessions.domain.repository.SessionRepository; @@ -11,6 +15,7 @@ public class AddNote extends UseCase { private final SessionRepository mSessionRepository; public AddNote(NoteRepository noteRepository, SessionRepository sessionRepository) { + Log.d("devlog", "create AddNote"); mNoteRepository = noteRepository; mSessionRepository = sessionRepository; } diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/model/ISessionDetail.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/model/ISessionDetail.java new file mode 100644 index 00000000..3db91613 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/model/ISessionDetail.java @@ -0,0 +1,10 @@ +package br.org.cesar.discordtime.stickysessions.domain.model; + +import java.util.List; + +public interface ISessionDetail { + String getId(); + String getName(); + List getTopics(); + String getCreatedAt(); +} diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/model/Session.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/model/Session.java index 1a24f110..10242c8a 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/model/Session.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/domain/model/Session.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Locale; -public class Session { +public class Session implements ISessionDetail { public String id; public List topics = null; public String createdAt; @@ -42,4 +42,25 @@ public int getDay() { } return 1; } + + @Override + public String getId() { + return id; + } + + @Override + public String getName() { + // TODO: Get the session name + return (topics.size() == 5) ? "Starfish" : "Gain & Pleasure"; + } + + @Override + public List getTopics() { + return topics; + } + + @Override + public String getCreatedAt() { + return createdAt; + } } diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/components/SessionComponent.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/components/SessionComponent.kt index 284b7217..bab563c8 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/components/SessionComponent.kt +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/components/SessionComponent.kt @@ -13,10 +13,10 @@ import br.org.cesar.discordtime.stickysessions.injectors.modules.SessionModule import br.org.cesar.discordtime.stickysessions.injectors.modules.SessionPresenterModule import br.org.cesar.discordtime.stickysessions.injectors.modules.ThreadModule import br.org.cesar.discordtime.stickysessions.injectors.modules.UserModule -import br.org.cesar.discordtime.stickysessions.ui.session.SessionActivity +import br.org.cesar.discordtime.stickysessions.ui.notes.NotesActivity import dagger.Component @Component(modules = [SessionPresenterModule::class, NoteModule::class, SessionModule::class, ThreadModule::class, ContextModule::class, ServerModule::class, UserModule::class, LoggerModule::class, NetworkModule::class, HttpLoggingInterceptorModule::class, HttpNetworkInterceptorModule::class, HttpModule::class, AuthModule::class]) interface SessionComponent { - fun inject(activity: SessionActivity) + fun inject(activity: NotesActivity) } diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/components/TopicNotesViewComponent.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/components/TopicNotesViewComponent.java new file mode 100644 index 00000000..28a0c945 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/components/TopicNotesViewComponent.java @@ -0,0 +1,37 @@ +package br.org.cesar.discordtime.stickysessions.injectors.components; + +import br.org.cesar.discordtime.stickysessions.injectors.modules.AuthModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.ContextModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.HttpLoggingInterceptorModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.HttpModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.HttpNetworkInterceptorModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.LoggerModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.NetworkModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.NoteModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.NoteTopicPresenterModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.ServerModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.SessionModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.ThreadModule; +import br.org.cesar.discordtime.stickysessions.injectors.modules.UserModule; +import br.org.cesar.discordtime.stickysessions.ui.notes.holder.NotesViewHolder; +import dagger.Component; + +@Component( + modules = { + NoteTopicPresenterModule.class, + NoteModule.class, + SessionModule.class, + ThreadModule.class, + ContextModule.class, + ServerModule.class, + UserModule.class, + LoggerModule.class, + NetworkModule.class, + HttpLoggingInterceptorModule.class, + HttpNetworkInterceptorModule.class, + HttpModule.class, + AuthModule.class + }) +public interface TopicNotesViewComponent { + void inject(NotesViewHolder view); +} diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/NoteTopicPresenterModule.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/NoteTopicPresenterModule.java new file mode 100644 index 00000000..432e4e04 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/NoteTopicPresenterModule.java @@ -0,0 +1,22 @@ +package br.org.cesar.discordtime.stickysessions.injectors.modules; + +import java.util.List; + +import br.org.cesar.discordtime.stickysessions.domain.model.Note; +import br.org.cesar.discordtime.stickysessions.domain.model.NoteFilter; +import br.org.cesar.discordtime.stickysessions.executor.IObservableUseCase; +import br.org.cesar.discordtime.stickysessions.presentation.notes.NotesContract; +import br.org.cesar.discordtime.stickysessions.presentation.notes.NotesPresenter; +import dagger.Module; +import dagger.Provides; + +@Module +public class NoteTopicPresenterModule { + @Provides + public NotesContract.Presenter getNoteTopicPresenter( + IObservableUseCase addNote, + IObservableUseCase removeNote, + IObservableUseCase> listNotes) { + return new NotesPresenter(listNotes, addNote, removeNote); + } +} diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/SessionPresenterModule.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/SessionPresenterModule.java index be352603..0e8706e8 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/SessionPresenterModule.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/injectors/modules/SessionPresenterModule.java @@ -1,12 +1,7 @@ package br.org.cesar.discordtime.stickysessions.injectors.modules; -import java.util.List; - -import br.org.cesar.discordtime.stickysessions.domain.model.Note; -import br.org.cesar.discordtime.stickysessions.domain.model.NoteFilter; import br.org.cesar.discordtime.stickysessions.domain.model.Session; import br.org.cesar.discordtime.stickysessions.executor.IObservableUseCase; -import br.org.cesar.discordtime.stickysessions.executor.ObservableUseCase; import br.org.cesar.discordtime.stickysessions.logger.Logger; import br.org.cesar.discordtime.stickysessions.presentation.session.SessionContract; import br.org.cesar.discordtime.stickysessions.presentation.session.SessionPresenter; @@ -19,14 +14,10 @@ public class SessionPresenterModule { @Provides public SessionContract.Presenter providesPresenter( IObservableUseCase enterSession, - IObservableUseCase addNote, - IObservableUseCase removeNote, - IObservableUseCase> listNotes, IObservableUseCase getSavedUser, Logger logger){ - return new SessionPresenter(enterSession, addNote, removeNote, listNotes, - getSavedUser, logger); + return new SessionPresenter(enterSession, getSavedUser, logger); } } diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/navigation/wrapper/ViewStarter.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/navigation/wrapper/ViewStarter.java index 604283cb..9f093053 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/navigation/wrapper/ViewStarter.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/navigation/wrapper/ViewStarter.java @@ -14,7 +14,7 @@ import br.org.cesar.discordtime.stickysessions.ui.lobby.LobbyActivity; import br.org.cesar.discordtime.stickysessions.ui.login.LoginActivity; import br.org.cesar.discordtime.stickysessions.ui.meeting.MeetingActivity; -import br.org.cesar.discordtime.stickysessions.ui.session.SessionActivity; +import br.org.cesar.discordtime.stickysessions.ui.notes.NotesActivity; public class ViewStarter implements IViewStarter { @@ -23,7 +23,7 @@ public class ViewStarter implements IViewStarter { put(ViewNames.LOGIN_ACTIVITY, LoginActivity.class); put(ViewNames.LOBBY_ACTIVITY, LobbyActivity.class); put(ViewNames.MEETING_ACTIVITY, MeetingActivity.class); - put(ViewNames.SESSION_ACTIVITY, SessionActivity.class); + put(ViewNames.SESSION_ACTIVITY, NotesActivity.class); put(ViewNames.LIST_ACTIVITY, ListSessionsActivity.class); }}; diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/list/ListSessionsPresenter.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/list/ListSessionsPresenter.java index f7fe6541..443531f6 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/list/ListSessionsPresenter.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/list/ListSessionsPresenter.java @@ -51,7 +51,7 @@ public void detachView() { @Override public void onLoad(String meetingId) { - mLogger.d(TAG, "onLoad list sessions "); + mLogger.d(TAG, "onLoad loadNotesForSession sessions "); if (meetingId != null && !meetingId.isEmpty()) { initObservers(); diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/lobby/LobbyPresenter.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/lobby/LobbyPresenter.java index 6caf2011..01af5393 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/lobby/LobbyPresenter.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/lobby/LobbyPresenter.java @@ -118,13 +118,13 @@ public void onError(Throwable e) { class ListSessionObserver extends DisposableSingleObserver { @Override public void onSuccess(Void aVoid) { - mLog.d(TAG, "list sessions success"); + mLog.d(TAG, "loadNotesForSession sessions success"); goNext(IRouter.LIST_SESSIONS); } @Override public void onError(Throwable e) { - mLog.d(TAG, "list session error" + e.getLocalizedMessage()); + mLog.d(TAG, "loadNotesForSession session error" + e.getLocalizedMessage()); // TODO: Pass meaningful text to view depending on error mView.displayError(""); } diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/INoteTopicDetail.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/INoteTopicDetail.kt new file mode 100644 index 00000000..0baef1f8 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/INoteTopicDetail.kt @@ -0,0 +1,7 @@ +package br.org.cesar.discordtime.stickysessions.presentation.notes + +interface INoteTopicDetail { + fun getTopicName(): String? + fun getUserId(): String? + fun getSessionId(): String? +} \ No newline at end of file diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NoteTopicDetail.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NoteTopicDetail.kt new file mode 100644 index 00000000..cfa38909 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NoteTopicDetail.kt @@ -0,0 +1,10 @@ +package br.org.cesar.discordtime.stickysessions.presentation.notes + +class NoteTopicDetail( + private val topicName: String?, + private val sessionId: String?, + private val userID: String?) : INoteTopicDetail { + override fun getTopicName() = topicName + override fun getSessionId() = sessionId + override fun getUserId() = userID +} \ No newline at end of file diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NotesContract.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NotesContract.kt new file mode 100644 index 00000000..d24cea6a --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NotesContract.kt @@ -0,0 +1,20 @@ +package br.org.cesar.discordtime.stickysessions.presentation.notes + +import br.org.cesar.discordtime.stickysessions.domain.model.Note + +interface NotesContract { + interface Presenter { + fun attachView(view: View) + fun detachView() + fun updateData(noteTopicDetail: INoteTopicDetail?) + fun onNewNoteClick() + } + + interface View { + fun displayTopicName(name: String) + fun displayNotes(notes: List) + fun displayLoading() + fun hideLoading() + fun clearNotes() + } +} \ No newline at end of file diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NotesPresenter.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NotesPresenter.kt new file mode 100644 index 00000000..cd97d850 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/notes/NotesPresenter.kt @@ -0,0 +1,82 @@ +package br.org.cesar.discordtime.stickysessions.presentation.notes + +import android.util.Log +import br.org.cesar.discordtime.stickysessions.domain.model.Note +import br.org.cesar.discordtime.stickysessions.domain.model.NoteFilter +import br.org.cesar.discordtime.stickysessions.executor.IObservableUseCase +import io.reactivex.observers.DisposableSingleObserver + +class NotesPresenter( + private val mListNotes: IObservableUseCase>?, + private val addNote: IObservableUseCase?, + private val removeNote: IObservableUseCase? +) : NotesContract.Presenter { + companion object { + const val TAG = "NotesPresenter" + } + + private var mView: NotesContract.View? = null + private var mNoteTopicDetail: INoteTopicDetail? = null + + override fun attachView(view: NotesContract.View) { + mView = view + } + + override fun detachView() { + mView = null + } + + override fun updateData(noteTopicDetail: INoteTopicDetail?) { + mNoteTopicDetail = noteTopicDetail + mView?.clearNotes() + mView?.displayTopicName(noteTopicDetail?.getTopicName() ?: "") + + loadNotesForSession() + } + + override fun onNewNoteClick() { + // TODO: Open Note Editor as new note. + } + + private fun getTopicName(): String = mNoteTopicDetail?.getTopicName() ?: "" + + private fun loadNotesForSession() { + mView?.displayLoading() + if (getTopicName() == "Start") { + mView?.displayNotes(getStart()) + } else { + mView?.displayNotes(listOf(Note( + "Description Lorem ipsum dolor sit amet, cons ect etur adipiscai elit, sed do eiusmod tempor. Lorem ipsum dolor sit amet, cons ect etur adipiscai elit, sed do eiusmod tempor.", + "user 1", + mNoteTopicDetail?.getTopicName(), + "session id"))) + } + mView?.hideLoading() + +// mListNotes?.execute(object: DisposableSingleObserver>() { +// override fun onSuccess(notes: List) { +// // TODO: Move this logic to a use case. +// mView?.displayNotes( +// notes.filter { note -> note.topic == mNoteTopicDetail?.getTopicName() }) +// mView?.hideLoading() +// } +// +// override fun onError(e: Throwable) { +// Log.e(TAG, "displayNotes: " + e.message) +// mView?.hideLoading() +// // TODO: show error on UI. +// } +// }, NoteFilter(mNoteTopicDetail?.getSessionId())) + } + + private fun getStart(): List = listOf(Note( + "Description Lorem ipsum dolor sit amet, cons ect etur adipiscai elit, sed do eiusmod tempor. Lorem ipsum dolor sit amet, cons ect etur adipiscai elit, sed do eiusmod tempor.", + "user 1", + mNoteTopicDetail?.getTopicName(), + "session id"), + Note( + "Testando, primeira nota", + "user 1", + mNoteTopicDetail?.getTopicName(), + "session id")) +} diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionContract.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionContract.java deleted file mode 100644 index a045ff59..00000000 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionContract.java +++ /dev/null @@ -1,37 +0,0 @@ -package br.org.cesar.discordtime.stickysessions.presentation.session; - -import java.util.List; - -import br.org.cesar.discordtime.stickysessions.domain.model.Note; - -public interface SessionContract { - - interface Presenter { - void attachView(SessionContract.View view); - void detachView(); - void onShareSession(); - void onAddNoteClicked(); - void addNewNote(String sessionId, String description); - void onNoteWidgetClicked(Note note); - void onResume(); - void currentSession(String sessionId); - void removeNote(Note note); - } - - interface View { - void addNoteToNoteList(Note note); - void shareSession(String sessionId); - void cleanNotes(); - void removeNote(Note note); - void startLoadingNote(); - void stopLoadingNote(); - void startLoadingAllNotes(); - void stopLoadingAllNotes(); - void displayAddNoteDialog(List topics); - void displaySession(); - void displayError(String message); - void displayNotes(List notes); - void displayErrorInvalidNotes(); - void displayNoteContent(Note note); - } -} diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionContract.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionContract.kt new file mode 100644 index 00000000..e38a03b3 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionContract.kt @@ -0,0 +1,22 @@ +package br.org.cesar.discordtime.stickysessions.presentation.session + +import br.org.cesar.discordtime.stickysessions.presentation.notes.INoteTopicDetail + +interface SessionContract { + interface Presenter { + fun attachView(view: View) + fun detachView() + fun onShareSession() + fun onResume() + fun currentSession(sessionId: String?) + } + + interface View { + fun shareSession(sessionId: String) + fun displaySession(sessionDetail: List) + fun displayError(message: String?) + fun startLoading() + fun stopLoading() + fun displayTitle(name: String?) + } +} \ No newline at end of file diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionPresenter.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionPresenter.java deleted file mode 100644 index 3759ed27..00000000 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionPresenter.java +++ /dev/null @@ -1,182 +0,0 @@ -package br.org.cesar.discordtime.stickysessions.presentation.session; - -import java.util.List; - -import br.org.cesar.discordtime.stickysessions.domain.model.Note; -import br.org.cesar.discordtime.stickysessions.domain.model.NoteFilter; -import br.org.cesar.discordtime.stickysessions.domain.model.Session; -import br.org.cesar.discordtime.stickysessions.executor.IObservableUseCase; -import br.org.cesar.discordtime.stickysessions.logger.Logger; -import io.reactivex.observers.DisposableSingleObserver; - -public class SessionPresenter implements SessionContract.Presenter { - - private static final String TAG = "SessionPresenter"; - private IObservableUseCase mEnterSession; - private IObservableUseCase mAddNote; - private IObservableUseCase mRemoveNote; - private IObservableUseCase> mListNotes; - private IObservableUseCase mGetSavedUser; - private Logger mLog; - private SessionContract.View mView; - private Session mActiveSession; - private String mSessionId; - private String mCurrentUser; - - public SessionPresenter(IObservableUseCase enterSession, - IObservableUseCase addNote, - IObservableUseCase removeNote, - IObservableUseCase> listNotes, - IObservableUseCase getSavedUser, - Logger logger) { - mEnterSession = enterSession; - mAddNote = addNote; - mRemoveNote = removeNote; - mListNotes = listNotes; - mGetSavedUser = getSavedUser; - mLog = logger; - } - - @Override - public void attachView(SessionContract.View view) { - mView = view; - } - - @Override - public void onResume() { - mView.startLoadingAllNotes(); - mGetSavedUser.execute(new DisposableSingleObserver() { - @Override - public void onSuccess(String userName) { - mCurrentUser = userName; - onEnterSession(); - } - - @Override - public void onError(Throwable e) { - mView.stopLoadingAllNotes(); - // TODO: Go back to login? - } - }, null); - } - - @Override - public void currentSession(String sessionId) { - mSessionId = sessionId; - } - - @Override - public void removeNote(Note note) { - mRemoveNote.execute(new DisposableSingleObserver() { - @Override - public void onSuccess(Object o) { - mView.removeNote(note); - } - - @Override - public void onError(Throwable e) { - mView.displayError(e.getMessage()); - } - }, note); - } - - @Override - public void detachView() { - mView = null; - disposeObservers(); - } - - private void disposeObservers() { - mEnterSession.dispose(); - mAddNote.dispose(); - mRemoveNote.dispose(); - mListNotes.dispose(); - mGetSavedUser.dispose(); - } - - - private void onEnterSession() { - mLog.d(TAG, "onEnterSession : "+mSessionId); - mEnterSession.execute(new DisposableSingleObserver() { - @Override - public void onSuccess(Session session) { - mActiveSession = session; - listNotesForCurrentSession(); - mView.displaySession(); - } - - @Override - public void onError(Throwable e) { - // todo : handle errors gracefully - mView.stopLoadingAllNotes(); - mView.displayError(e.getMessage()); - } - }, mSessionId); - } - - private void listNotesForCurrentSession() { - if (mActiveSession != null && mActiveSession.id != null) { - mListNotes.execute(new DisposableSingleObserver>() { - @Override - public void onSuccess(List notes) { - mView.stopLoadingAllNotes(); - mView.displayNotes(notes); - } - - @Override - public void onError(Throwable e) { - mView.stopLoadingAllNotes(); - mView.displayErrorInvalidNotes(); - } - }, new NoteFilter(mActiveSession.id)); - } else { - mView.stopLoadingAllNotes(); - mView.displayErrorInvalidNotes(); - } - } - - @Override - public void onShareSession() { - if(mActiveSession != null) { - mView.shareSession(mActiveSession.id); - } - } - - @Override - public void onAddNoteClicked() { - - if (mActiveSession != null && mActiveSession.topics != null) { - List topics = mActiveSession.topics; - mView.displayAddNoteDialog(topics); - } - } - - @Override - public void addNewNote(String topic, String description) { - if (mActiveSession != null && mActiveSession.id != null && mCurrentUser != null) { - mView.startLoadingNote(); - Note note = new Note(description, mCurrentUser, topic, mActiveSession.id); - mAddNote.execute(new DisposableSingleObserver() { - - @Override - public void onSuccess(Note note) { - mView.stopLoadingNote(); - mView.addNoteToNoteList(note); - } - - @Override - public void onError(Throwable e) { - mView.stopLoadingNote(); - mView.displayError(e.getMessage()); - } - }, note); - } - } - - @Override - public void onNoteWidgetClicked(Note note) { - if (note != null) { - mView.displayNoteContent(note); - } - } -} diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionPresenter.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionPresenter.kt new file mode 100644 index 00000000..52be24c9 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/presentation/session/SessionPresenter.kt @@ -0,0 +1,91 @@ +package br.org.cesar.discordtime.stickysessions.presentation.session + +import br.org.cesar.discordtime.stickysessions.domain.model.ISessionDetail +import br.org.cesar.discordtime.stickysessions.domain.model.Session +import br.org.cesar.discordtime.stickysessions.executor.IObservableUseCase +import br.org.cesar.discordtime.stickysessions.logger.Logger +import br.org.cesar.discordtime.stickysessions.presentation.notes.INoteTopicDetail +import br.org.cesar.discordtime.stickysessions.presentation.notes.NoteTopicDetail +import io.reactivex.observers.DisposableSingleObserver + +class SessionPresenter( + private val mEnterSession: IObservableUseCase, + private val mGetSavedUser: IObservableUseCase, + private val mLog: Logger +) : SessionContract.Presenter { + companion object { + @JvmStatic private val TAG = "SessionPresenter" + } + + private var mView: SessionContract.View? = null + private var mActiveSession: Session? = null + private var mSessionId: String? = null + private var mCurrentUser: String? = null + + override fun attachView(view: SessionContract.View) { + mView = view + } + + override fun onResume() { + mView?.startLoading() + mGetSavedUser.execute(object: DisposableSingleObserver() { + override fun onSuccess(userName: String) { + mCurrentUser = userName + onEnterSession() + } + + override fun onError(e: Throwable) { + mView?.stopLoading() + // TODO: Go back to login? + } + }, null) + } + + override fun currentSession(sessionId: String?) { + mSessionId = sessionId + } + + override fun detachView() { + mView = null + disposeObservers() + } + + override fun onShareSession() { + if (isSessionActive()) { + mView?.shareSession(mActiveSession?.id ?: "") + } + } + + private fun onEnterSession() { + mLog.d(TAG, "onEnterSession : $mSessionId") + mEnterSession.execute(object : DisposableSingleObserver() { + override fun onSuccess(session: Session) { + mActiveSession = session + + mLog.d(TAG, "displaySession: " + mActiveSession?.getId()) + mView?.stopLoading() + mView?.displayTitle(mActiveSession?.name) + val notes = getNoteTopicDetailList(mActiveSession) + if (notes?.isNotEmpty() == true) mView?.displaySession(notes) + // TODO: else show Empty notes UI + } + + override fun onError(e: Throwable) { + // Todo : handle errors gracefully + mView?.stopLoading() + mView?.displayError(e.message) + } + }, mSessionId) + } + + private fun disposeObservers() { + mEnterSession.dispose() + mGetSavedUser.dispose() + } + + private fun isSessionActive(): Boolean = mActiveSession?.id != null + + private fun getNoteTopicDetailList(sessionDetail: ISessionDetail?): List? = + sessionDetail?.topics?.map { + topicName -> NoteTopicDetail(topicName, mSessionId, mCurrentUser) } +} \ No newline at end of file diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/adapters/NoteAdapter.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/adapters/NoteAdapter.java deleted file mode 100644 index abb0ba13..00000000 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/adapters/NoteAdapter.java +++ /dev/null @@ -1,157 +0,0 @@ -package br.org.cesar.discordtime.stickysessions.ui.adapters; - -import android.animation.AnimatorInflater; -import android.animation.AnimatorSet; -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.animation.BounceInterpolator; -import android.widget.ProgressBar; -import android.widget.TextView; - -import java.security.InvalidParameterException; -import java.util.ArrayList; -import java.util.List; - -import androidx.recyclerview.widget.RecyclerView; -import br.org.cesar.discordtime.stickysessions.R; -import br.org.cesar.discordtime.stickysessions.domain.model.Note; - -public class NoteAdapter extends RecyclerView.Adapter { - - private final Context mContext; - private List mNotes; - private NoteAdapterCallback mCallback; - private boolean isLoading; - - public NoteAdapter(Context context) { - mContext = context; - mNotes = new ArrayList<>(); - } - - public void addNote(Note note) { - mNotes.add(note); - notifyItemInserted(mNotes.size() - 1); - } - - public void removeNote(Note note) { - for (int i = 0; i < mNotes.size(); i++) { - Note element = mNotes.get(i); - if (note.equals(element)) { - mNotes.remove(note); - notifyItemRemoved(i); - } - } - } - - public interface NoteAdapterCallback { - void onItemClicked(Note note); - } - - public void setNotes(List notes) { - - if (notes == null) { - throw new InvalidParameterException("note list could not be null"); - } - - mNotes.clear(); - mNotes.addAll(notes); - // TODO: fix animation crash -> IndexOutOfBoundsException: Inconsistency detected. - //notifyItemRangeInserted(0, mNotes.size()); - notifyDataSetChanged(); - } - - public void setCallback(NoteAdapterCallback callback) { - if (callback != null) { - mCallback = callback; - } - } - - @Override - public NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - Context context = parent.getContext(); - View view = LayoutInflater.from(context).inflate(R.layout.note_element, parent, false); - - return new NoteViewHolder(view); - } - - @Override - public void onBindViewHolder(NoteViewHolder holder, int position) { - Note note = mNotes.get(position); - holder.mContent.setText(note.description); - holder.mTitle.setText(note.topic); - if(isLoading && position == mNotes.size()-1){ - holder.progressBar.setVisibility(View.VISIBLE); - } else { - holder.progressBar.setVisibility(View.GONE); - } - AnimatorSet animator = (AnimatorSet) AnimatorInflater.loadAnimator( - mContext, R.animator.show_note_animator); - - animator.setTarget(holder.itemView); - animator.setInterpolator(new BounceInterpolator()); - animator.setDuration(750); - animator.start(); - - holder.mContent.getViewTreeObserver().addOnGlobalLayoutListener( - new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - int lineHeight = holder.mContent.getLineHeight(); - int height = holder.mContent.getHeight(); - - if (lineHeight != 0) { - int maxLines = height / lineHeight; - holder.mContent.setMaxLines(maxLines); - holder.mContent.invalidate(); - } - - holder.mContent.getViewTreeObserver().removeOnGlobalLayoutListener(this); - } - }); - } - - @Override - public int getItemCount() { - return mNotes == null ? 0 : mNotes.size(); - } - - public void startLoading(){ - if(!isLoading){ - isLoading = true; - addNote(new Note()); - } - } - - public void stopLoading(){ - if(isLoading){ - isLoading = false; - removeNote(new Note()); - } - } - - class NoteViewHolder extends RecyclerView.ViewHolder { - TextView mTitle; - TextView mContent; - ProgressBar progressBar; - NoteViewHolder(View itemView) { - super(itemView); - - itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - int position = getAdapterPosition(); - Note note = mNotes.get(position); - mCallback.onItemClicked(note); - } - }); - - mTitle = itemView.findViewById(R.id.title_note_element); - mContent = itemView.findViewById(R.id.description_note_element); - progressBar = itemView.findViewById(R.id.progress_bar); - } - - } -} diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/NotesActivity.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/NotesActivity.kt new file mode 100644 index 00000000..84745236 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/NotesActivity.kt @@ -0,0 +1,152 @@ +package br.org.cesar.discordtime.stickysessions.ui.notes; + +import android.content.Intent +import android.os.Bundle +import android.text.TextUtils +import android.util.Log +import android.view.Menu +import android.view.View +import android.widget.ProgressBar +import android.widget.TextView +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.LinearSnapHelper +import androidx.recyclerview.widget.RecyclerView +import br.org.cesar.discordtime.stickysessions.R +import br.org.cesar.discordtime.stickysessions.app.StickySessionApplication +import br.org.cesar.discordtime.stickysessions.presentation.notes.INoteTopicDetail +import br.org.cesar.discordtime.stickysessions.presentation.session.SessionContract +import br.org.cesar.discordtime.stickysessions.ui.ExtraNames +import br.org.cesar.discordtime.stickysessions.ui.notes.adapters.NotesByNotesAdapter +import javax.inject.Inject + +class NotesActivity : AppCompatActivity(), SessionContract.View { + companion object { + const val TAG = "SessionActivity" + } + + private val mRecyclerView by lazy { findViewById(R.id.user_topic_session) } + private val mProgressBar by lazy { findViewById(R.id.progress_bar) } + private val mToolbarTitleTextView by lazy { findViewById(R.id.toolbar_title) } + private lateinit var mNotesByTopicAdapter: NotesByNotesAdapter + + @Inject + lateinit var mPresenter: SessionContract.Presenter + + override fun onCreate(savedInstanceState: Bundle?) { + setTheme(R.style.AppTheme) + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_session) + + (applicationContext as StickySessionApplication).inject(this) + + bindView() + configureSession() + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + configureSession() + } + + override fun onResume() { + super.onResume() + mPresenter.onResume() + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.session_menu, menu) + return true + } + + override fun onDestroy() { + super.onDestroy() + mPresenter.detachView() + } + + /* SessionContract.View overrides --- */ + + override fun displayError(message: String?) { + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + } + + override fun startLoading() { + mRecyclerView.visibility = View.INVISIBLE + mProgressBar.visibility = View.VISIBLE + } + + override fun stopLoading() { + mRecyclerView.visibility = View.VISIBLE + mProgressBar.visibility = View.GONE + } + + override fun displayTitle(name: String?) { + mToolbarTitleTextView.text = name + } + + override fun shareSession(sessionId: String){ + // TODO: move this code to a util class + startActivity(Intent(Intent.ACTION_SEND).apply { + type = "text/plain" + putExtra(Intent.EXTRA_TEXT, String.format(getString(R.string.share_session, sessionId))) + }) + } + + override fun displaySession(sessionDetail: List) { + mNotesByTopicAdapter.replaceData(sessionDetail) + } + + private fun bindView() { + configureToolbar() + + initializeTopicSessionList() + mPresenter.attachView(this) + } + + private fun configureToolbar() { + setSupportActionBar(findViewById(R.id.toolbar)) + + supportActionBar?.apply { + setHomeAsUpIndicator(R.drawable.ic_back) + setDisplayHomeAsUpEnabled(true) + setDisplayShowHomeEnabled(true) + } + } + + private fun initializeTopicSessionList() { + mRecyclerView.layoutManager = LinearLayoutManager(this).apply { + orientation = RecyclerView.HORIZONTAL + } + // TODO: Check if this is necessary +// mRecyclerView.itemAnimator = ItemAnimator(this); + + // TODO: Check if this is necessary +// LinearSnapHelper snapHelper = new LinearSnapHelper(); +// snapHelper.attachToRecyclerView(mRecyclerView); + + mNotesByTopicAdapter = NotesByNotesAdapter() + mRecyclerView.adapter = mNotesByTopicAdapter + } + + private fun configureSession() { + //Enter in a session by link + if (Intent.ACTION_VIEW == intent.action) { + val uri = intent.data + if (uri != null) { + val sessionId = uri.getQueryParameter(ExtraNames.SESSION_ID) + Log.d(TAG, "sessionId $sessionId") + mPresenter.currentSession(sessionId) + } else { + //TODO error message to null data + Log.d(TAG, "null sessionId.") + } + //Enter in a session by Lobby + } else if(!TextUtils.isEmpty(intent.getStringExtra(ExtraNames.SESSION_ID))) { + val sessionId = intent.getStringExtra(ExtraNames.SESSION_ID) + Log.d(TAG, "sessionId $sessionId") + mPresenter.currentSession(sessionId) + } + } +} diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/adapters/NoteAdapter.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/adapters/NoteAdapter.kt new file mode 100644 index 00000000..3547c8ad --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/adapters/NoteAdapter.kt @@ -0,0 +1,49 @@ +package br.org.cesar.discordtime.stickysessions.ui.notes.adapters; + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import br.org.cesar.discordtime.stickysessions.R +import br.org.cesar.discordtime.stickysessions.domain.model.Note +import br.org.cesar.discordtime.stickysessions.ui.notes.holder.NoteViewHolder + +class NoteAdapter : RecyclerView.Adapter() { + private var notes: MutableList = mutableListOf() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder { + val view: View = LayoutInflater.from(parent.context).inflate( + R.layout.item_note, parent, false); + return NoteViewHolder(view); + } + + override fun getItemCount(): Int = notes.size + + override fun onBindViewHolder(holder: NoteViewHolder, position: Int) { + holder.updateData(getItem(position)) + } + + fun addNote(note: Note) { + notes.add(note) + notifyItemInserted(notes.size - 1) + } + + fun removeNote(note: Note) { + notes.indexOf(note).let { + if (it >= 0) { + notes.remove(note) + notifyItemRemoved(it) + } + } + } + + fun setNotes(notes: List) { + this.notes.clear() + this.notes.addAll(notes) + // TODO: fix animation crash -> IndexOutOfBoundsException: Inconsistency detected. + //notifyItemRangeInserted(0, mNotes.size()) + notifyDataSetChanged() + } + + private fun getItem(position: Int): Note = notes[position] +} diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/adapters/NotesByNotesAdapter.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/adapters/NotesByNotesAdapter.kt new file mode 100644 index 00000000..70307b3a --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/adapters/NotesByNotesAdapter.kt @@ -0,0 +1,26 @@ +package br.org.cesar.discordtime.stickysessions.ui.notes.adapters + +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import br.org.cesar.discordtime.stickysessions.presentation.notes.INoteTopicDetail +import br.org.cesar.discordtime.stickysessions.ui.notes.holder.NotesViewHolder + +class NotesByNotesAdapter : RecyclerView.Adapter() { + private var mNoteTopicDetailList: List = emptyList() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) + = NotesViewHolder.createView(parent) + + override fun getItemCount(): Int = mNoteTopicDetailList.size + + override fun onBindViewHolder(holder: NotesViewHolder, position: Int) = + holder.getPresenter().updateData(getItem(position)) + + + fun replaceData(sessionDetail: List) { + mNoteTopicDetailList = sessionDetail + notifyDataSetChanged() + } + + private fun getItem(position: Int): INoteTopicDetail? = mNoteTopicDetailList[position] +} \ No newline at end of file diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/custom/ItemAnimator.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/custom/ItemAnimator.java similarity index 98% rename from app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/custom/ItemAnimator.java rename to app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/custom/ItemAnimator.java index 07db1f93..9f14eb44 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/custom/ItemAnimator.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/custom/ItemAnimator.java @@ -1,4 +1,4 @@ -package br.org.cesar.discordtime.stickysessions.ui.session.custom; +package br.org.cesar.discordtime.stickysessions.ui.notes.custom; import android.animation.Animator; import android.animation.AnimatorInflater; diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/custom/NoteGridLayoutManager.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/custom/NoteGridLayoutManager.java similarity index 86% rename from app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/custom/NoteGridLayoutManager.java rename to app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/custom/NoteGridLayoutManager.java index 846e094c..26e53d9f 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/custom/NoteGridLayoutManager.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/custom/NoteGridLayoutManager.java @@ -1,7 +1,6 @@ -package br.org.cesar.discordtime.stickysessions.ui.session.custom; +package br.org.cesar.discordtime.stickysessions.ui.notes.custom; import android.content.Context; -import android.util.Log; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/custom/SquaredConstraintLayout.java b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/custom/SquaredConstraintLayout.java similarity index 91% rename from app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/custom/SquaredConstraintLayout.java rename to app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/custom/SquaredConstraintLayout.java index 884e7f1d..71f79a0f 100644 --- a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/session/custom/SquaredConstraintLayout.java +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/custom/SquaredConstraintLayout.java @@ -1,4 +1,4 @@ -package br.org.cesar.discordtime.stickysessions.ui.session.custom; +package br.org.cesar.discordtime.stickysessions.ui.notes.custom; import android.content.Context; import android.util.AttributeSet; diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/holder/NoteViewHolder.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/holder/NoteViewHolder.kt new file mode 100644 index 00000000..70646009 --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/holder/NoteViewHolder.kt @@ -0,0 +1,27 @@ +package br.org.cesar.discordtime.stickysessions.ui.notes.holder + +import android.view.View +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import br.org.cesar.discordtime.stickysessions.R +import br.org.cesar.discordtime.stickysessions.domain.model.Note + +class NoteViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + private val mTitle = itemView.findViewById(R.id.text_note_topic) + private val mContent = itemView.findViewById(R.id.text_note_description) + private val menuView = itemView.findViewById(R.id.image_menu) + + fun updateData(note: Note) { + mContent?.text = note.description + mTitle?.text = note.topic + + menuView.setOnClickListener { + // TODO: Show option menu + } + + itemView.setOnClickListener { + // TODO: Implement that + } + } +} \ No newline at end of file diff --git a/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/holder/NotesViewHolder.kt b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/holder/NotesViewHolder.kt new file mode 100644 index 00000000..08140dff --- /dev/null +++ b/app/src/main/java/br/org/cesar/discordtime/stickysessions/ui/notes/holder/NotesViewHolder.kt @@ -0,0 +1,115 @@ +package br.org.cesar.discordtime.stickysessions.ui.notes.holder + +import android.content.Context +import android.graphics.Rect +import android.view.LayoutInflater +import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE +import android.view.ViewGroup +import android.widget.Button +import android.widget.TextView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import br.org.cesar.discordtime.stickysessions.R +import br.org.cesar.discordtime.stickysessions.app.StickySessionApplication +import br.org.cesar.discordtime.stickysessions.domain.model.Note +import br.org.cesar.discordtime.stickysessions.presentation.notes.NotesContract +import br.org.cesar.discordtime.stickysessions.ui.notes.adapters.NoteAdapter +import java.util.ArrayList +import javax.inject.Inject + +class NotesViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), + NotesContract.View, View.OnClickListener { + + private val mTopicNameTextView = itemView.findViewById(R.id.text_note_topic) + private val mNotesList = itemView.findViewById(R.id.list_notes) + private val mNewNoteButton = itemView.findViewById