Skip to content
This repository has been archived by the owner on Jul 6, 2024. It is now read-only.

Commit

Permalink
Crush backlog for release (#96)
Browse files Browse the repository at this point in the history
* Replace TODOs with tickets in backlog

* Add adapter for FitnessDetailsFragment playlist

* Add scroll view to settings fragment

* Remove skip button in Onboarding permissions

* Fix soft lock on selecting fallback playlist

* Fix typo
  • Loading branch information
george-lim authored Aug 17, 2020
1 parent 68dce3f commit 29c90d9
Show file tree
Hide file tree
Showing 15 changed files with 146 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package com.bruno.android.ui.fitnessdetails;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.bruno.android.R;
import com.bruno.android.models.FitnessModel;
Expand Down Expand Up @@ -45,11 +49,12 @@ public class FitnessDetailsFragment extends Fragment implements FitnessDetailsVi
private TextView txtStatsDistance;
private TextView txtStatsSteps;
private TextView txtStatsClock;
private LinearLayout runTracklist;
private RecyclerView playlistRecyclerView;

// MARK: - Private members

private FitnessDetailsViewModel viewModel;
private FitnessDetailsPlaylistAdapter playlistAdapter;

// MARK: - Lifecycle methods

Expand All @@ -63,7 +68,12 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
txtStatsDistance = view.findViewById(R.id.text_view_stats_distance);
txtStatsSteps = view.findViewById(R.id.text_view_stats_steps);
txtStatsClock = view.findViewById(R.id.text_view_stats_clock);
runTracklist = view.findViewById(R.id.linear_layout_fitness_detail_tracklist);
playlistRecyclerView = view.findViewById(R.id.playlist_recycler_view);

int[] trackColours = getResources().getIntArray(R.array.colorRouteList);
playlistAdapter = new FitnessDetailsPlaylistAdapter(trackColours);
playlistRecyclerView.setAdapter(playlistAdapter);

return view;
}

Expand Down Expand Up @@ -91,29 +101,22 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat

// MARK: - Private methods

// TODO: Use an adapter instead of manually adding view holders.
private void setupTracklist(final List<BrunoTrack> tracks) {
int[] routeColours = getResources().getIntArray(R.array.colorRouteList);
int colourIndex = 0;

for (BrunoTrack track : tracks) {
View viewHolderItemView = getLayoutInflater()
.inflate(R.layout.view_holder_fitness_details, null);
ImageView musicNote = viewHolderItemView
.findViewById(R.id.image_view_fitness_details_holder_music);
private void setupPlaylist(final List<BrunoTrack> tracks) {
playlistRecyclerView.setHasFixedSize(true);
playlistRecyclerView.setLayoutManager(
new LinearLayoutManager(requireActivity().getApplicationContext())
);

musicNote.setColorFilter(routeColours[colourIndex]);
colourIndex = (colourIndex + 1) % routeColours.length;
DividerItemDecoration itemDecoration = new DividerItemDecoration(
playlistRecyclerView.getContext(),
DividerItemDecoration.VERTICAL
);

TextView songName = viewHolderItemView
.findViewById(R.id.text_view_fitness_details_holder_song);
songName.setText(track.getName());
Drawable dividerDrawable = ContextCompat.getDrawable(requireActivity(), R.drawable.list_divider);
itemDecoration.setDrawable(dividerDrawable);
playlistRecyclerView.addItemDecoration(itemDecoration);

TextView artist = viewHolderItemView
.findViewById(R.id.text_view_fitness_details_holder_artist);
artist.setText(track.getArtists());
runTracklist.addView(viewHolderItemView);
}
playlistAdapter.setData(tracks);
}

// MARK: - FitnessDetailsViewModelDelegate methods
Expand Down Expand Up @@ -156,7 +159,7 @@ public void setupUI(final String leaderboardUserTimeText,
break;
}

setupTracklist(tracks);
setupPlaylist(tracks);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.bruno.android.ui.fitnessdetails;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bruno.android.R;
import com.bruno.android.music.BrunoTrack;

import java.util.ArrayList;
import java.util.List;

public class FitnessDetailsPlaylistAdapter extends RecyclerView.Adapter<FitnessDetailsPlaylistViewHolder> {

// MARK: - Private members

private int[] trackColours;
private List<BrunoTrack> data;

// MARK: - Lifecycle methods

public FitnessDetailsPlaylistAdapter(final int[] trackColours) {
this.trackColours = trackColours;
this.data = new ArrayList<>();
}

// MARK: - Public methods

public void setData(final List<BrunoTrack> data) {
this.data = data;
notifyDataSetChanged();
}

// MARK: - RecyclerView.ViewHolder methods

@NonNull
@Override
public FitnessDetailsPlaylistViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View viewHolderItemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.view_holder_fitness_details_playlist, parent, false);
return new FitnessDetailsPlaylistViewHolder(viewHolderItemView);
}

@Override
public void onBindViewHolder(@NonNull FitnessDetailsPlaylistViewHolder holder, int position) {
holder.populate(trackColours[position % trackColours.length], data.get(position));
}

@Override
public int getItemCount() {
return data.size();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.bruno.android.ui.fitnessdetails;

import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bruno.android.R;
import com.bruno.android.music.BrunoTrack;

public class FitnessDetailsPlaylistViewHolder extends RecyclerView.ViewHolder {

// MARK: - Private members

private ImageView trackIcon;
private TextView trackName;
private TextView trackArtists;

// MARK: - Lifecycle methods

public FitnessDetailsPlaylistViewHolder(@NonNull View itemView) {
super(itemView);
trackIcon = itemView.findViewById(R.id.fitness_details_playlist_track_icon);
trackName = itemView.findViewById(R.id.fitness_details_playlist_track_name);
trackArtists = itemView.findViewById(R.id.fitness_details_playlist_track_artists);
}

// MARK: - Public methods

public void populate(int musicNoteColour, final BrunoTrack track) {
trackIcon.setColorFilter(musicNoteColour);
trackName.setText(track.getName());
trackArtists.setText(track.getArtists());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ public class FitnessRecordsFragment extends Fragment
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fitness_records, container, false);
adapter = new FitnessRecordsAdapter(this);
fitnessRecordsRecyclerView = view.findViewById(R.id.recycler_view_fitness_record);

adapter = new FitnessRecordsAdapter(this);
fitnessRecordsRecyclerView.setAdapter(adapter);
return view;
}
Expand Down Expand Up @@ -79,7 +80,6 @@ public void setupUI() {
fitnessRecordsRecyclerView.setLayoutManager(
new LinearLayoutManager(requireActivity().getApplicationContext())
);
fitnessRecordsRecyclerView.setAdapter(adapter);

DividerItemDecoration itemDecoration = new DividerItemDecoration(
fitnessRecordsRecyclerView.getContext(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
active_internet_status = view.findViewById(R.id.active_internet_status);
spotify_status = view.findViewById(R.id.spotify_status);
btnAllowAccess = view.findViewById(R.id.btn_allow_access);

Button btnSkip = view.findViewById(R.id.btn_skip);
btnSkip.setOnClickListener(this::handleSkip);
btnAllowAccess.setOnClickListener(this::handleAllowAccess);
return view;
}
Expand All @@ -69,10 +66,6 @@ public void onResume() {
viewModel.updateUserAccess();
}

private void handleSkip(final View view) {
viewModel.handleSkip();
}

private void handleAllowAccess(final View view) {
viewModel.handleAllowAccess();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,6 @@ public OnboardingPermissionViewModel(final Context context, final OnboardingPerm
this.delegate = delegate;
}

public void handleSkip() {
if (isAllAccessAllowed()) {
delegate.moveToNextTab();
} else if (!accessToSpotify) {
showSpotifyNotInstallPopUp();
} else {
delegate.showPopUp(
context.getResources().getString(R.string.onboarding_missing_access_title),
context.getResources().getString(R.string.onboarding_missing_access_text),
context.getResources().getString(R.string.ok_button),
(dialogInterface, i) -> delegate.moveToNextTab(),
true
);
}
}

public void handleAllowAccess() {
// All access are granted by the user, automatically move to next tab
if (isAllAccessAllowed()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
@Override
public void onResume() {
super.onResume();
// This call is needed to be in onResume because ViewPager used for onBoarding have a tendency to
// create view in previous tab to enhance performance.
// This also allows us to re-sync user playlist when they added a new on after seeing they have none.
viewModel.getUserPlaylistLibrary();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class FallbackPlaylistViewModel {
private boolean ongoingRequest;
private PlaylistMetadata fallbackPlaylist;
public final String TAG = this.getClass().getSimpleName();
private boolean hasShownSpotifyError;

public FallbackPlaylistViewModel(final Context context,
final FallbackPlaylistAction wrapperDelegate,
Expand All @@ -45,6 +46,10 @@ public void setCurrentPlaylistAsFallBack(PlaylistMetadata playlist) {
}

public void getUserPlaylistLibrary() {
if (hasShownSpotifyError) {
return;
}

// Check if there is an ongoing process
// Since this is call by onResume, when auth view return, we don't want duplicate request.
if (ongoingRequest) {
Expand Down Expand Up @@ -191,6 +196,7 @@ private void showNotPremiumUser() {
}

private void showSpotifyError(final String errorText) {
hasShownSpotifyError = true;
wrapperDelegate.updatePrimaryAction(
FallbackPlaylistAction.ActionType.QUIT,
view -> delegate.quitApp());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,6 @@ private void onRouteCompleted() {
hasCompletedRoute = true;
model.completeRouteNavigation();

// TODO: Implement a route completion screen.
delegate.showAlertDialog(
resources.getString(R.string.run_completion_title),
resources.getString(R.string.run_completion_message),
Expand Down
7 changes: 3 additions & 4 deletions app/src/main/res/layout/fragment_fitness_details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,11 @@
android:textSize="24sp"
android:textStyle="bold" />

<LinearLayout
android:id="@+id/linear_layout_fitness_detail_tracklist"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/playlist_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />

android:scrollbars="vertical" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
12 changes: 0 additions & 12 deletions app/src/main/res/layout/fragment_onboarding_permission.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,6 @@
layout="@layout/permission_status" />
</LinearLayout>

<Button
android:id="@+id/btn_skip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:text="@string/onboarding_permission_skip"
android:textColor="@color/colorDisable"
app:layout_constraintBottom_toTopOf="@id/btn_allow_access"
android:layout_marginBottom="15dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />

<Button
android:id="@+id/btn_allow_access"
style="@style/OnboardingPrimaryActionButton"
Expand Down
17 changes: 11 additions & 6 deletions app/src/main/res/layout/fragment_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,23 @@
layout="@layout/toolbar_layout"
app:layout_constraintTop_toTopOf="parent"/>

<LinearLayout
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/appbar_settings">

<include layout="@layout/settings_user_preferences" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<include layout="@layout/settings_debug_preferences" />
<include layout="@layout/settings_user_preferences" />

<include layout="@layout/settings_about_bruno" />
<include layout="@layout/settings_debug_preferences" />

</LinearLayout>
<include layout="@layout/settings_about_bruno" />

</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Loading

0 comments on commit 29c90d9

Please sign in to comment.