Skip to content

Commit d1cfec5

Browse files
leeyh20iamareebjamal
authored andcommitted
feat: Add view model for DayScheduleFragment (fossasia#2328)
1 parent 1a1f915 commit d1cfec5

File tree

5 files changed

+117
-122
lines changed

5 files changed

+117
-122
lines changed

android/app/src/main/java/org/fossasia/openevent/core/schedule/DayScheduleAdapter.java

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,41 +19,19 @@
1919

2020
import java.util.ArrayList;
2121
import java.util.List;
22-
import java.util.Locale;
23-
24-
import io.reactivex.Observable;
25-
import io.realm.RealmResults;
26-
import timber.log.Timber;
2722

2823
public class DayScheduleAdapter extends BaseRVAdapter<Session, DayScheduleViewHolder> implements StickyRecyclerHeadersAdapter<HeaderViewHolder> {
2924

3025
private Context context;
31-
private String eventDate;
3226
private OnBookmarkSelectedListener onBookmarkSelectedListener;
33-
3427
private RealmDataRepository realmRepo = RealmDataRepository.getDefaultInstance();
35-
3628
private ArrayList<String> tracks = new ArrayList<>();
37-
private List<Session> copyOfSessions = new ArrayList<>();
3829

3930
public DayScheduleAdapter(List<Session> sessions, Context context) {
4031
super(sessions);
41-
this.copyOfSessions = new ArrayList<>(sessions);
4232
this.context = context;
4333
}
4434

45-
public void setCopy(List<Session> sessions) {
46-
copyOfSessions = sessions;
47-
}
48-
49-
public String getEventDate() {
50-
return eventDate;
51-
}
52-
53-
public void setEventDate(String eventDate) {
54-
this.eventDate = eventDate;
55-
}
56-
5735
@Override
5836
public DayScheduleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
5937
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
@@ -78,24 +56,6 @@ public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
7856
super.onDetachedFromRecyclerView(recyclerView);
7957
}
8058

81-
public void filter(String constraint) {
82-
final String query = constraint.toLowerCase(Locale.getDefault());
83-
84-
((RealmResults<Session>) copyOfSessions).sort(SortOrder.sortTypeSchedule());
85-
86-
List<Session> filteredSessions = Observable.fromIterable(copyOfSessions)
87-
.filter(session -> session.getTitle().toLowerCase().contains(query))
88-
.toList().blockingGet();
89-
90-
Timber.d("Filtering done total results %d", filteredSessions.size());
91-
92-
if (filteredSessions.isEmpty()) {
93-
Timber.e("No results published. There is an error in query. Check " + getClass().getName() + " filter!");
94-
}
95-
96-
animateTo(filteredSessions);
97-
}
98-
9959
@Override
10060
public long getHeaderId(int position) {
10161
String id = "";

android/app/src/main/java/org/fossasia/openevent/core/schedule/DayScheduleFragment.java

Lines changed: 36 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.fossasia.openevent.core.schedule;
22

3+
import android.arch.lifecycle.ViewModelProviders;
34
import android.content.Context;
45
import android.os.Bundle;
56
import android.support.annotation.NonNull;
@@ -29,27 +30,21 @@
2930
import org.fossasia.openevent.common.ui.Views;
3031
import org.fossasia.openevent.common.ui.base.BaseFragment;
3132
import org.fossasia.openevent.common.ui.recyclerview.stickyheadersrecyclerview.StickyRecyclerHeadersDecoration;
32-
import org.fossasia.openevent.common.utils.SortOrder;
3333
import org.fossasia.openevent.common.utils.Utils;
3434
import org.fossasia.openevent.config.StrategyRegistry;
3535
import org.fossasia.openevent.core.bookmark.OnBookmarkSelectedListener;
3636
import org.fossasia.openevent.data.Session;
37-
import org.fossasia.openevent.data.repository.RealmDataRepository;
38-
3937
import java.lang.ref.WeakReference;
4038
import java.util.ArrayList;
41-
import java.util.Collections;
4239
import java.util.List;
4340

4441
import butterknife.BindView;
45-
import io.realm.RealmResults;
4642
import timber.log.Timber;
4743

4844
public class DayScheduleFragment extends BaseFragment implements SearchView.OnQueryTextListener {
4945

50-
final private String SEARCH = "searchText";
51-
5246
private Context context;
47+
private String date;
5348
private String searchText = "";
5449
private SearchView searchView;
5550

@@ -58,15 +53,12 @@ public class DayScheduleFragment extends BaseFragment implements SearchView.OnQu
5853
@BindView(R.id.txt_no_schedule) TextView noSchedule;
5954
@BindView(R.id.txt_no_result_schedule) protected TextView noResultsSchedule;
6055

61-
private List<Session> sessions = new ArrayList<>();
6256
private List<Session> filteredSessions = new ArrayList<>();
6357
private DayScheduleAdapter dayScheduleAdapter;
64-
private OnBookmarkSelectedListener onBookmarkSelectedListener;
6558

66-
private String date;
67-
private RealmDataRepository realmRepo = RealmDataRepository.getDefaultInstance();
68-
private RealmResults<Session> realmResults;
59+
private OnBookmarkSelectedListener onBookmarkSelectedListener;
6960
private RecyclerView.AdapterDataObserver adapterDataObserver;
61+
private DayScheduleFragmentViewModel dayScheduleFragmentViewModel;
7062

7163
@Override
7264
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -85,32 +77,22 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
8577
Utils.registerIfUrlValid(swipeRefreshLayout, this, this::refresh);
8678
setUpRecyclerView();
8779

88-
if (savedInstanceState != null && savedInstanceState.getString(SEARCH) != null) {
89-
searchText = savedInstanceState.getString(SEARCH);
90-
}
80+
// Set up view model
81+
dayScheduleFragmentViewModel = ViewModelProviders.of(this).get(DayScheduleFragmentViewModel.class);
82+
searchText = dayScheduleFragmentViewModel.getSearchText();
9183

92-
realmResults = realmRepo.getSessionsByDate(date, SortOrder.sortTypeSchedule());
93-
realmResults.addChangeListener((sortedSessions, orderedCollectionChangeSet) -> {
94-
sessions.clear();
95-
sessions.addAll(sortedSessions);
84+
loadSessions();
85+
handleVisibility();
86+
return view;
87+
}
9688

89+
private void loadSessions() {
90+
dayScheduleFragmentViewModel.getSessionsByDate(date, searchText).observe(DayScheduleFragment.this, sessions -> {
9791
filteredSessions.clear();
98-
filteredSessions.addAll(sortedSessions);
99-
100-
dayScheduleAdapter.setCopy(sortedSessions);
92+
filteredSessions.addAll(sessions);
10193
dayScheduleAdapter.notifyDataSetChanged();
102-
if (!Utils.isEmpty(searchText))
103-
dayScheduleAdapter.filter(searchText);
104-
105-
if(SortOrder.sortOrderSchedule() == SortOrder.SORT_ORDER_DESCENDING)
106-
Collections.reverse(filteredSessions);
107-
10894
handleVisibility();
10995
});
110-
111-
handleVisibility();
112-
113-
return view;
11496
}
11597

11698
private void setUpRecyclerView() {
@@ -121,7 +103,6 @@ private void setUpRecyclerView() {
121103
dayRecyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
122104
dayRecyclerView.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
123105
dayRecyclerView.setAdapter(dayScheduleAdapter);
124-
dayScheduleAdapter.setEventDate(date);
125106

126107
final StickyRecyclerHeadersDecoration headersDecoration = new StickyRecyclerHeadersDecoration(dayScheduleAdapter);
127108
dayRecyclerView.addItemDecoration(headersDecoration);
@@ -134,39 +115,26 @@ public void onChanged() {
134115
dayScheduleAdapter.registerAdapterDataObserver(adapterDataObserver);
135116
}
136117

137-
public void filter(List<String> selectedTracks) {
138-
if(dayScheduleAdapter == null)
139-
return;
140-
141-
realmRepo.getSessionsByDate(date, SortOrder.sortTypeSchedule())
142-
.addChangeListener((sortedSessions, orderedCollectionChangeSet) -> {
143-
sessions.clear();
144-
sessions.addAll(sortedSessions);
145-
146-
filteredSessions.clear();
147-
if (selectedTracks.isEmpty()) {
148-
filteredSessions.addAll(sessions);
149-
} else {
150-
for(int i = 0; i < sessions.size() ; i++) {
151-
String trackName = sessions.get(i).getTrack().getName();
152-
if (selectedTracks.contains(trackName)) {
153-
filteredSessions.add(sessions.get(i));
154-
}
155-
}
156-
157-
if(searchText!=null)
158-
dayScheduleAdapter.filter(searchText);
159-
}
160-
161-
if(SortOrder.sortOrderSchedule() == SortOrder.SORT_ORDER_DESCENDING)
162-
Collections.reverse(filteredSessions);
163-
164-
dayScheduleAdapter.notifyDataSetChanged();
165-
166-
handleVisibility();
167-
});
118+
public void filterByTracks(List<String> selectedTracks) {
119+
dayScheduleFragmentViewModel.getSortedSessionsByTracks(searchText, selectedTracks).observe(DayScheduleFragment.this, trackSessions -> {
120+
filteredSessions.clear();
121+
filteredSessions.addAll(trackSessions);
122+
dayScheduleAdapter.notifyDataSetChanged();
123+
handleVisibility();
124+
});
125+
}
126+
127+
public void filterByQuery(String query) {
128+
searchText = query;
129+
dayScheduleFragmentViewModel.getSessionsBySearchText(searchText).observe(DayScheduleFragment.this, matchingSessions -> {
130+
filteredSessions.clear();
131+
filteredSessions.addAll(matchingSessions);
132+
dayScheduleAdapter.notifyDataSetChanged();
133+
handleVisibility();
134+
});
168135
}
169136

137+
170138
private void handleVisibility() {
171139
if (dayRecyclerView != null && noSchedule != null) {
172140
if (!filteredSessions.isEmpty()) {
@@ -177,7 +145,6 @@ private void handleVisibility() {
177145
}
178146
}
179147

180-
181148
@Override
182149
protected int getLayoutResource() {
183150
return R.layout.list_schedule;
@@ -190,7 +157,6 @@ public void onDestroyView() {
190157
dayScheduleAdapter.unregisterAdapterDataObserver(adapterDataObserver);
191158

192159
// Remove listeners to fix memory leak
193-
realmResults.removeAllChangeListeners();
194160
if(swipeRefreshLayout != null) swipeRefreshLayout.setOnRefreshListener(null);
195161
if(searchView != null) searchView.setOnQueryTextListener(null);
196162
}
@@ -202,7 +168,8 @@ public void onSessionsDownloadDone(SessionDownloadEvent event) {
202168
if (event.isState()) {
203169
Timber.i("Schedule download completed");
204170
if (searchView != null && !searchView.getQuery().toString().isEmpty() && !searchView.isIconified()) {
205-
dayScheduleAdapter.filter(searchView.getQuery().toString());
171+
searchText = searchView.getQuery().toString();
172+
filterByQuery(searchText);
206173
}
207174
} else {
208175
Timber.i("Schedule download failed");
@@ -212,19 +179,10 @@ public void onSessionsDownloadDone(SessionDownloadEvent event) {
212179
}
213180
}
214181

215-
@Override
216-
public void onSaveInstanceState(@NonNull Bundle bundle) {
217-
if (isAdded() && searchView != null) {
218-
bundle.putString(SEARCH, searchText);
219-
}
220-
super.onSaveInstanceState(bundle);
221-
}
222-
223182
@Override
224183
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
225184
super.onCreateOptionsMenu(menu, inflater);
226185

227-
searchText = "";
228186
inflater.inflate(R.menu.menu_schedule, menu);
229187

230188
MenuItem item = menu.findItem(R.id.action_search_schedule);
@@ -238,10 +196,9 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
238196
@Override
239197
public boolean onQueryTextChange(String query) {
240198
searchText = query;
241-
242-
dayScheduleAdapter.filter(searchText);
199+
filterByQuery(searchText);
200+
dayScheduleAdapter.animateTo(filteredSessions);
243201
Utils.displayNoResults(noResultsSchedule, dayRecyclerView, noSchedule, dayScheduleAdapter.getItemCount());
244-
245202
return true;
246203
}
247204

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.fossasia.openevent.core.schedule;
2+
3+
import android.arch.lifecycle.LiveData;
4+
import android.arch.lifecycle.ViewModel;
5+
6+
import org.fossasia.openevent.common.arch.FilterableRealmLiveData;
7+
import org.fossasia.openevent.data.Session;
8+
import org.fossasia.openevent.data.repository.RealmDataRepository;
9+
import org.fossasia.openevent.common.utils.SortOrder;
10+
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.Locale;
14+
15+
import io.reactivex.functions.Predicate;
16+
import io.realm.RealmResults;
17+
import io.realm.Sort;
18+
19+
public class DayScheduleFragmentViewModel extends ViewModel {
20+
21+
private RealmDataRepository realmRepo;
22+
private RealmResults<Session> sessions;
23+
private List<String> tracks = new ArrayList<>();
24+
private FilterableRealmLiveData<Session> filterableSessions;
25+
private String searchText = "";
26+
27+
public DayScheduleFragmentViewModel() {
28+
realmRepo = RealmDataRepository.getDefaultInstance();
29+
}
30+
31+
public String getSearchText() { return searchText; }
32+
33+
public LiveData<List<Session>> getSessionsByDate(String date, String searchText) {
34+
sessions = loadSessions(date);
35+
return getSortedSessionsByTracks(searchText, new ArrayList<>());
36+
}
37+
38+
public LiveData<List<Session>> getSortedSessionsByTracks(String searchText, List<String> selectedTracks) {
39+
Sort sortOrder;
40+
if (SortOrder.sortOrderSchedule() == SortOrder.SORT_ORDER_DESCENDING) {
41+
sortOrder = Sort.DESCENDING;
42+
} else {
43+
sortOrder = Sort.ASCENDING;
44+
}
45+
sessions = sessions.sort(SortOrder.sortTypeSchedule(), sortOrder);
46+
filterableSessions = RealmDataRepository.asFilterableLiveData(sessions);
47+
filterableSessions.filter(getPredicateWithSearchAndTracks(searchText, selectedTracks));
48+
return filterableSessions;
49+
}
50+
51+
public LiveData<List<Session>> getSessionsBySearchText(String searchText) {
52+
filterableSessions.filter(getPredicateWithSearchAndTracks(searchText, tracks));
53+
return filterableSessions;
54+
}
55+
56+
private Predicate<Session> getPredicateWithSearchAndTracks(String searchText, List<String> selectedTracks) {
57+
this.searchText = searchText;
58+
this.tracks = selectedTracks;
59+
final String query = this.searchText.toLowerCase(Locale.getDefault());
60+
61+
Predicate<Session> predicate = session -> {
62+
boolean hasQuery = session.getTitle()
63+
.toLowerCase(Locale.getDefault())
64+
.contains(query);
65+
66+
boolean isInTracks = true;
67+
if (!this.tracks.isEmpty()) {
68+
isInTracks = this.tracks.contains(session.getTrack().getName());
69+
}
70+
return hasQuery && isInTracks;
71+
};
72+
return predicate;
73+
}
74+
75+
private RealmResults<Session> loadSessions(String date) {
76+
return realmRepo.getSessionsByDate(date);
77+
}
78+
}

android/app/src/main/java/org/fossasia/openevent/core/schedule/ScheduleFragment.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ private void notifyUpdate(int position, List<String> selectedTracks) {
157157
if(position == -1)
158158
position = viewPager.getCurrentItem();
159159

160-
((DayScheduleFragment) adapter.getItem(position)).filter(selectedTracks);
160+
((DayScheduleFragment) adapter.getItem(position)).filterByTracks(selectedTracks);
161161
}
162162

163163
@Override

android/app/src/main/java/org/fossasia/openevent/data/repository/RealmDataRepository.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,8 @@ public RealmResults<Session> getSessionsByLocation(String location) {
384384
return realm.where(Session.class).equalTo("microlocation.name", location).findAllSortedAsync(Session.START_TIME);
385385
}
386386

387-
public RealmResults<Session> getSessionsByDate(String date, String sortCriteria) {
388-
return realm.where(Session.class).equalTo("startDate", date).findAllSortedAsync(sortCriteria);
387+
public RealmResults<Session> getSessionsByDate(String date) {
388+
return realm.where(Session.class).equalTo("startDate", date).findAllAsync();
389389
}
390390

391391
public RealmResults<Session> getSessionsByDateFiltered(String date, String query, String sortCriteria) {

0 commit comments

Comments
 (0)