From 0af2b7e31ca09f4322a4378e6d66e809c01b51f0 Mon Sep 17 00:00:00 2001 From: Niko Strijbol Date: Thu, 19 Sep 2019 12:46:32 +0200 Subject: [PATCH 1/7] Update SKO line-up Some fields in the API changed, and polish some scrolling behaviour. --- .../zeus/hydra/sko/OverviewActivity.java | 3 +- .../ugent/zeus/hydra/sko/lineup/Artist.java | 76 ++++--- .../sko/lineup/ArtistDetailsActivity.java | 16 +- .../zeus/hydra/sko/lineup/ArtistOrTitle.java | 1 - .../hydra/sko/lineup/ArtistViewHolder.java | 2 +- .../zeus/hydra/sko/lineup/LineupFragment.java | 24 +- .../zeus/hydra/sko/lineup/LineupRequest.java | 1 + .../hydra/sko/lineup/LineupViewModel.java | 4 +- .../res/drawable/gradient_black_bottom.xml | 6 +- .../main/res/layout/activity_sko_artist.xml | 2 +- .../res/layout/item_sko_lineup_artist.xml | 1 + app/src/main/res/values/formatters.xml | 1 - .../java/be/ugent/zeus/hydra/TestApp.java | 3 + app/src/test/resources/sko_lineup.json | 215 +++++++++--------- 14 files changed, 196 insertions(+), 159 deletions(-) diff --git a/app/src/main/java/be/ugent/zeus/hydra/sko/OverviewActivity.java b/app/src/main/java/be/ugent/zeus/hydra/sko/OverviewActivity.java index c33beded8..2e48578f5 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/sko/OverviewActivity.java +++ b/app/src/main/java/be/ugent/zeus/hydra/sko/OverviewActivity.java @@ -3,10 +3,11 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; -import androidx.annotation.Nullable; import android.view.Menu; import android.view.MenuItem; +import androidx.annotation.Nullable; + import be.ugent.zeus.hydra.R; import be.ugent.zeus.hydra.common.network.Endpoints; import be.ugent.zeus.hydra.common.ui.BaseActivity; diff --git a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/Artist.java b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/Artist.java index 9f60e7336..a61fd8aa6 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/Artist.java +++ b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/Artist.java @@ -6,9 +6,12 @@ import android.os.Parcelable; import android.provider.CalendarContract; +import androidx.annotation.Nullable; + +import java9.util.Objects; + import be.ugent.zeus.hydra.R; import be.ugent.zeus.hydra.utils.DateUtils; -import java9.util.Objects; import org.threeten.bp.LocalDateTime; import org.threeten.bp.OffsetDateTime; import org.threeten.bp.format.DateTimeFormatter; @@ -25,13 +28,14 @@ public final class Artist implements Parcelable { private static final String LOCATION = "Sint-Pietersplein, Gent"; private String name; + private String title; private OffsetDateTime start; private OffsetDateTime end; - private String banner; private String image; private String content; + private String description; private String stage; - private String link; + private int index; /** * @return The name of the act. @@ -62,6 +66,7 @@ public OffsetDateTime getEnd() { * * @return The converted start date. */ + @SuppressWarnings("WeakerAccess") public LocalDateTime getLocalStart() { return getStart() == null ? null : DateUtils.toLocalDateTime(getStart()); } @@ -74,28 +79,39 @@ public LocalDateTime getLocalStart() { * * @return The converted end date. */ + @SuppressWarnings("WeakerAccess") public LocalDateTime getLocalEnd() { return getEnd() == null ? null : DateUtils.toLocalDateTime(getEnd()); } - public String getBanner() { - return banner; - } - public String getImage() { return image; } - public String getContent() { - return content; + @Nullable + public String getDescription() { + if (this.content == null || this.content.isEmpty()) { + if (this.description == null || this.description.isEmpty()) { + return null; + } else { + return this.description; + } + } else { + return this.content; + } } + @SuppressWarnings("WeakerAccess") public String getStage() { return stage; } - public String getLink() { - return link; + public int getIndex() { + return index; + } + + public String getTitle() { + return title; } /** @@ -109,6 +125,7 @@ public String getLink() { * * @return The text to display. */ + @SuppressWarnings("WeakerAccess") public String getDisplayDate(Context context) { LocalDateTime start = getLocalStart(); @@ -118,33 +135,35 @@ public String getDisplayDate(Context context) { return context.getString(R.string.sko_artist_time_none); } - DateTimeFormatter fullFormatter = DateTimeFormatter.ofPattern(context.getString(R.string.formatter_sko_artist_full)); DateTimeFormatter shortFormatter = DateTimeFormatter.ofPattern(context.getString(R.string.formatter_sko_artist_hour_only)); if (start == null) { - return context.getString(R.string.sko_artist_time_end, end.format(fullFormatter)); + return context.getString(R.string.sko_artist_time_end, end.format(shortFormatter)); } else if (end == null) { - return context.getString(R.string.sko_artist_time_start, start.format(fullFormatter)); + return context.getString(R.string.sko_artist_time_start, start.format(shortFormatter)); } else { // Both are not null. - String startString = start.format(fullFormatter); - String endString; - if (start.getDayOfMonth() == end.getDayOfMonth()) { - endString = end.format(shortFormatter); - } else { - endString = end.format(fullFormatter); - } - + String startString = start.format(shortFormatter); + String endString = end.format(shortFormatter); return context.getString(R.string.sko_artist_time, startString, endString); } } + /** + * Get an intent to add the artist to the calendar. The intent will contain all necessary data. + * + * @return The intent. + */ + @SuppressWarnings("WeakerAccess") public Intent addToCalendarIntent() { Intent intent = new Intent(Intent.ACTION_INSERT) .setData(CalendarContract.Events.CONTENT_URI) .putExtra(CalendarContract.Events.EVENT_LOCATION, LOCATION) .putExtra(CalendarContract.Events.TITLE, getName()) .putExtra(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY); + if (getDescription() != null) { + intent.putExtra(CalendarContract.Events.DESCRIPTION, getDescription()); + } if (getStart() != null) { intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, getStart().toInstant().toEpochMilli()); } @@ -160,6 +179,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; Artist artist = (Artist) o; return Objects.equals(name, artist.name) && + Objects.equals(title, artist.title) && Objects.equals(start, artist.start) && Objects.equals(end, artist.end) && Objects.equals(stage, artist.stage); @@ -167,7 +187,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(name, start, end, stage); + return Objects.hash(name, title, start, end, stage); } @Override @@ -178,13 +198,14 @@ public int describeContents() { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(this.name); + dest.writeString(this.title); dest.writeSerializable(this.start); dest.writeSerializable(this.end); - dest.writeString(this.banner); dest.writeString(this.image); dest.writeString(this.content); dest.writeString(this.stage); - dest.writeString(this.link); + dest.writeString(this.description); + dest.writeInt(this.index); } public Artist() { @@ -192,13 +213,14 @@ public Artist() { protected Artist(Parcel in) { this.name = in.readString(); + this.title = in.readString(); this.start = (OffsetDateTime) in.readSerializable(); this.end = (OffsetDateTime) in.readSerializable(); - this.banner = in.readString(); this.image = in.readString(); this.content = in.readString(); this.stage = in.readString(); - this.link = in.readString(); + this.description = in.readString(); + this.index = in.readInt(); } public static final Creator CREATOR = new Creator() { diff --git a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistDetailsActivity.java b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistDetailsActivity.java index b466d4315..006b6d155 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistDetailsActivity.java +++ b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistDetailsActivity.java @@ -4,19 +4,19 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.os.Parcelable; import android.provider.MediaStore; -import androidx.annotation.Nullable; import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.Nullable; + import be.ugent.zeus.hydra.R; -import be.ugent.zeus.hydra.common.reporting.Reporting; import be.ugent.zeus.hydra.common.reporting.BaseEvents; import be.ugent.zeus.hydra.common.reporting.Event; +import be.ugent.zeus.hydra.common.reporting.Reporting; import be.ugent.zeus.hydra.common.ui.BaseActivity; import be.ugent.zeus.hydra.utils.NetworkUtils; import com.squareup.picasso.Picasso; @@ -34,7 +34,7 @@ public class ArtistDetailsActivity extends BaseActivity { public static Intent start(Context context, Artist artist) { Intent intent = new Intent(context, ArtistDetailsActivity.class); - intent.putExtra(PARCEL_ARTIST, (Parcelable) artist); + intent.putExtra(PARCEL_ARTIST, artist); return intent; } @@ -52,6 +52,7 @@ protected void onCreate(Bundle savedInstanceState) { ImageView headerImage = findViewById(R.id.header_image); title.setText(artist.getName()); + setTitle(artist.getName()); if (artist.getImage() != null) { Picasso.get().load(artist.getImage()).fit().centerInside().into(headerImage); @@ -59,8 +60,8 @@ protected void onCreate(Bundle savedInstanceState) { date.setText(artist.getDisplayDate(this)); - if (!TextUtils.isEmpty(artist.getContent())) { - content.setText(artist.getContent()); + if (!TextUtils.isEmpty(artist.getDescription())) { + content.setText(artist.getDescription()); } else { content.setText(R.string.sko_artist_no_content); } @@ -111,8 +112,7 @@ public Bundle getParams() { BaseEvents.Params names = Reporting.getEvents().params(); Bundle params = new Bundle(); params.putString(names.itemCategory(), Artist.class.getSimpleName()); - String id = artist.getLink() == null ? "linkless" : artist.getLink(); - params.putString(names.itemId(), id); + params.putString(names.itemId(), artist.getName()); params.putString(names.itemName(), artist.getName()); return params; } diff --git a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistOrTitle.java b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistOrTitle.java index d33262272..199ffbd9a 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistOrTitle.java +++ b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistOrTitle.java @@ -1,6 +1,5 @@ package be.ugent.zeus.hydra.sko.lineup; - import androidx.annotation.NonNull; import java9.util.Objects; diff --git a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistViewHolder.java b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistViewHolder.java index f12948db5..5e85da6a0 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistViewHolder.java +++ b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/ArtistViewHolder.java @@ -46,7 +46,7 @@ public void populate(final ArtistOrTitle artistOrTitle) { this.artist = artistOrTitle.getArtist(); title.setText(artist.getName()); date.setText(artist.getDisplayDate(date.getContext())); - Picasso.get().load(artist.getBanner()).into(image); + Picasso.get().load(artist.getImage()).into(image); itemView.setOnClickListener(v -> { Intent intent = ArtistDetailsActivity.start(v.getContext(), artist); v.getContext().startActivity(intent); diff --git a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupFragment.java b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupFragment.java index 04d311bbf..4d43d0416 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupFragment.java +++ b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupFragment.java @@ -1,30 +1,31 @@ package be.ugent.zeus.hydra.sko.lineup; -import androidx.lifecycle.ViewModelProviders; import android.os.Bundle; +import android.util.Log; +import android.view.*; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.material.snackbar.Snackbar; import androidx.fragment.app.Fragment; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.lifecycle.ViewModelProviders; import androidx.recyclerview.widget.RecyclerView; -import android.util.Log; -import android.view.*; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import java.util.List; import java.util.Map; +import java9.util.stream.Collectors; +import java9.util.stream.Stream; +import java9.util.stream.StreamSupport; + import be.ugent.zeus.hydra.R; import be.ugent.zeus.hydra.common.arch.observers.PartialErrorObserver; import be.ugent.zeus.hydra.common.arch.observers.ProgressObserver; import be.ugent.zeus.hydra.common.arch.observers.SuccessObserver; import be.ugent.zeus.hydra.common.ui.BaseActivity; -import java9.util.stream.Collectors; -import java9.util.stream.Stream; -import java9.util.stream.StreamSupport; +import com.google.android.material.snackbar.Snackbar; import static be.ugent.zeus.hydra.utils.FragmentUtils.requireBaseActivity; -import static be.ugent.zeus.hydra.utils.FragmentUtils.requireView; /** * Show the lineup. @@ -51,6 +52,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c } @Override + @SuppressWarnings("DuplicatedCode") // Cannot easily deduplicate public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -76,7 +78,7 @@ private void receiveData(@NonNull List data) { .collect(Collectors.groupingBy(Artist::getStage)); // Merge the sorted stages back into one flat list while prepending the stage as a title for each section. - // This might be faster with a traditional loop, but the streams are fancier. + // This might be faster with a traditional loop, but streams are fancier. List masterList = StreamSupport.stream(stages.entrySet()) .flatMap(e -> Stream.concat( @@ -89,7 +91,7 @@ private void receiveData(@NonNull List data) { } @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.menu_refresh, menu); BaseActivity.tintToolbarIcons(requireBaseActivity(this).requireToolbar(), menu, R.id.action_refresh); } diff --git a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupRequest.java b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupRequest.java index 33a81f19a..b495b45b3 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupRequest.java +++ b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupRequest.java @@ -1,6 +1,7 @@ package be.ugent.zeus.hydra.sko.lineup; import android.content.Context; + import androidx.annotation.NonNull; import be.ugent.zeus.hydra.common.network.Endpoints; diff --git a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupViewModel.java b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupViewModel.java index 76c634837..289215b54 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupViewModel.java +++ b/app/src/main/java/be/ugent/zeus/hydra/sko/lineup/LineupViewModel.java @@ -2,11 +2,11 @@ import android.app.Application; +import java.util.List; + import be.ugent.zeus.hydra.common.request.Request; import be.ugent.zeus.hydra.common.ui.RequestViewModel; -import java.util.List; - /** * This class cannot be package private due to technical limitations. * diff --git a/app/src/main/res/drawable/gradient_black_bottom.xml b/app/src/main/res/drawable/gradient_black_bottom.xml index 4e83300ac..7a00c1ab0 100644 --- a/app/src/main/res/drawable/gradient_black_bottom.xml +++ b/app/src/main/res/drawable/gradient_black_bottom.xml @@ -2,8 +2,8 @@ \ No newline at end of file diff --git a/app/src/main/res/layout/activity_sko_artist.xml b/app/src/main/res/layout/activity_sko_artist.xml index ed18bd410..af523661c 100644 --- a/app/src/main/res/layout/activity_sko_artist.xml +++ b/app/src/main/res/layout/activity_sko_artist.xml @@ -20,7 +20,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" - app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed|snap" + app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed|snap|exitUntilCollapsed" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginStart="48dp" app:expandedTitleMarginEnd="64dp" diff --git a/app/src/main/res/layout/item_sko_lineup_artist.xml b/app/src/main/res/layout/item_sko_lineup_artist.xml index 57f4bf7af..289e1d9eb 100644 --- a/app/src/main/res/layout/item_sko_lineup_artist.xml +++ b/app/src/main/res/layout/item_sko_lineup_artist.xml @@ -22,6 +22,7 @@ android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="centerCrop" + android:maxHeight="128dp" android:contentDescription="@string/content_desc_artist_image"/> - dd/MM - HH:mm @string/formatter_general_hour_only HH:mm diff --git a/app/src/test/java/be/ugent/zeus/hydra/TestApp.java b/app/src/test/java/be/ugent/zeus/hydra/TestApp.java index a55ead8b6..72aa628a9 100644 --- a/app/src/test/java/be/ugent/zeus/hydra/TestApp.java +++ b/app/src/test/java/be/ugent/zeus/hydra/TestApp.java @@ -35,5 +35,8 @@ protected void onCreateInitialise() { Reporting.syncPermissions(this); setupPicasso(); + + // Do not use SSL + System.setProperty("javax.net.ssl.trustStore", "NONE"); } } \ No newline at end of file diff --git a/app/src/test/resources/sko_lineup.json b/app/src/test/resources/sko_lineup.json index fe404563b..d324e65f1 100644 --- a/app/src/test/resources/sko_lineup.json +++ b/app/src/test/resources/sko_lineup.json @@ -1,136 +1,145 @@ [ { - "content": "Na het grote succes van zijn tour met De Fanfaar in 2014 en 2015 besloot Urbanus om alles gewoon nog eens opnieuw te doen. En gelukkig maar, want de show die voordien al in de AB liep, zit vol sappige oneliners, geestige verhalen en ook een streepje muziek natuurlijk. Het is er met andere woorden eentje om niet te missen. Woensdag 28 september op het Sint-Pietersplein komt Urbanus SPECIAAL voor jullie, samen met zijn band vol getatoeëerde rockers uit het Brusselse liedjes spelen. Wees daar of wees een vierkant.", - "name": "Urbanus \u0026 De Fanfaar", - "start": "2017-09-28T13:00:00+02:00", - "end": "2017-09-28T14:00:00+02:00", - "image": "https://studentkickoff.be/assets/images/artists/urbanus.jpg", - "banner": "http://old.studentkickoff.be/sites/default/files/styles/groto_foto-980x/public/Urbanus%26DeFanfaar-%20Happy%20%28C%29%20Kim%20Vreys%202000.jpg?itok=ZaMOPmDP", - "stage": "Main Stage" - }, - { - "content": "Suspenders’ Gravity bestaat eveneens uit vier ware virtuozen die luisteren naar de namen Seppe, Robbert, Rutger en Tamatoi. Ze wonnen in april de publieksprijs op de Student Rock Rally in de Charlatan en zijn volledig klaar om de grote podia te veroveren. Met nummers van hun EP “The General Theory of Relativity”, een mix van 90’s grunge, punk en hardrock, zullen ze het Sint-Pietersplein laten daveren. Niet alleen de muziek, maar ook de kledingstijl van de groep laat menig modebewuste sterveling niet onberoerd. De leden staan steevast op het podium met een trendy paar bretellen en wie het komende jaar niet wil doorbrengen met wedgies, gestolen lunchgeld of bekladde lockers schaft er zich nu best ook al een lading aan.", - "name": "Suspenders' Gravity", - "start": "2017-09-28T14:20:00+02:00", - "end": "2017-09-28T15:00:00+02:00", - "image": "https://studentkickoff.be/assets/images/artists/suspenders.jpg", - "banner": "http://old.studentkickoff.be/sites/default/files/styles/groto_foto-980x/public/12038200_523161904509058_992930554292417050_n.jpg?itok=fWEW7uZd", - "stage": "Main Stage" - }, - { - "content": "Momma Said So bestaat uit vier ongelooflijk getalenteerde knakkers. Kasper, Hannah, Roel en Inti brachten eind 2015 hun debuut-EP uit en met dat pareltje hebben ze de hartjes van onze jury en zowat de rest van de hele ganse wereld (dat komt nog, geloof ons) veroverd. Met hun eclectische popmuziek zorgen ze ervoor dat er van stilstaan op het Sint-Pietersplein geen sprake is. Aan jullie om ervoor te zorgen dat je ze gezien hebt voor ze ‘cool’ waren.", - "name": "Momma Said So", - "start": "2017-09-28T15:20:00+02:00", - "end": "2017-09-28T16:00:00+02:00", - "image": "https://studentkickoff.be/assets/images/artists/momma.jpg", - "banner": "http://old.studentkickoff.be/sites/default/files/styles/groto_foto-980x/public/mommasaidso_studentrockrally16_gertjandebaets_04202016_222.jpg?itok=wOpx_6di", - "stage": "Main Stage" + "content": "", + "name": "Adrian b2b Barbosa", + "index": 1, + "start": "2019-09-26T15:00:00+02:00", + "end": "2019-09-26T17:00:00+02:00", + "description": "Adrian started 5 years ago at H2O club and Decadance!, he rapidly was booked by Cirque Magique and became a Sondag resident for quite a time. His sound can be described as a twist between minimal and house. Loving the drum elements of music you can expect a rythmic workout while listening to his sets. He also found home at MUZI cartel 1 year ago and carefully curates together with Lebawski & Barbosa the newly born label.

\"Deep with a funky touch\"
Laurent Joël alias Barbosa is a Ghent-based DJ. Laurent always had a passion for disco, funky house and 80s music. During his exchange project in Barcelona, where he played in several local clubs, he discovered the world of minimal, deep and micro house. As a part of MUZI cartel and with his own concept INFERNO he brings best of both worlds together.", + "title": "Adrian b2b Barbosa", + "stage": "Second Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/adrianb2bbarbosa.jpg" }, { - "content": "Binnenkort kan iedereen “ICH BIN VERLIEBT, AUF ANGELA MERKEL” op het Sint-Pietersplein komen schreeuwen want jawel, niemand minder dan de jongens van Gestapo Knallmuzik zullen ons op 28 september gezelschap houden. Hun diepgaande nummers over schuurpapier, Frank und Sabine en vliegen met Luftschwanza zijn op zijn minst ‘onvergetelijk’ te noemen. Woensdag 28 september, speciaal voor jullie helemaal vanuit Berlijn op het Sint-Pietersplein!", - "name": "Gestapo Knallmuzik", - "start": "2017-09-28T16:20:00+02:00", - "end": "2017-09-28T17:15:00+02:00", - "image": "https://studentkickoff.be/assets/images/artists/gestapo.jpg", - "banner": "http://old.studentkickoff.be/sites/default/files/styles/groto_foto-980x/public/Vibe_Banner_2015.jpg?itok=xGMVaR_-", - "stage": "Main Stage" + "content": "", + "name": "DJ YOLOTANKER", + "start": "2019-09-25T13:00:00+02:00", + "end": "2019-09-25T14:00:00+02:00", + "index": 1, + "description": "When DJ YOLOTANKER released his first two singles, a Foie Gras remix of Christoff’s ‘Onze Vader’ and #AMEN, the world wide web stopped and took a breath. The tunes and videoclip became instant internet phenomena and so did the DJ. Since then DJ YOLOTANKER is travelling the world serving nothing but the best classics, sing-alongs & polonaises with a serious hardstyle.", + "title": "DJ YOLOTANKER", + "stage": "Main Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/yolotanker.jpg" }, { - "content": "De Gentse groep Wallace Vanborn is voor velen geen onbekende meer. In 2014 openden ze de Main Stage van Pukkelpop en waren ze te gast op festivals als Dour, Boomtown en Eurosonic. De driekoppige band met als leden Ian Clement, Dries Hoof en Sylvester Vanborm, wordt wel eens vergeleken met Queens Of The Stone Age. Verwacht jullie met nummers als ‘Wastelands’ aan een gezonde dosis stonerrock en knallers van platen uit hun laatste album ‘The Orb We Absorb’. Fun Fact - Het album is opgenomen in de woestijn. VET.", - "name": "Wallace Vanborn", - "start": "2017-09-28T17:45:00+02:00", - "end": "2017-09-28T18:45:00+02:00", - "image": "https://studentkickoff.be/assets/images/artists/wallace.jpg", - "banner": "http://old.studentkickoff.be/sites/default/files/styles/groto_foto-980x/public/slider05.jpg?itok=KQJ-OWgg", - "stage": "Main Stage" + "content": "", + "name": "Heckman", + "index": 2, + "start": "2019-09-25T17:00:00+02:00", + "end": "2019-09-25T19:00:00+02:00", + "description": "Part STUNTMAN
Part HECKMAN!
100% pepper addict which means HECKMAN will always spice things up!
As his father taught him “He who eats pepper, can give pepper”… which makes even less sense in English than in Dutch…", + "title": "Heckman", + "stage": "Second Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/heckman.jpg" }, { - "content": "We kennen Jonas van Geel van programma’s als ‘Tegen de Sterren op’ en het lijkt ook nog niet zo lang geleden dat Jelle Cleymans de rol van Evert vertolkte in de populaire Ketnetserie ‘Spring’. Het tijdperk van Spring mag dan misschien al voorbij zijn (Das om te rotten eh!), het vervolg erop is minstens even goed. Cleymans \u0026amp; Van Geel gaan het Sint-Pietersplein plat spelen met een geweldige coverband en een repertoire vol Vlaamse klassiekers met een eigenzinnige twist. Dit MOET je gezien hebben.", - "name": "Cleymans \u0026 Van Geel", - "start": "2017-09-28T19:20:00+02:00", - "end": "2017-09-28T20:50:00+02:00", - "image": "https://studentkickoff.be/assets/images/artists/cleymans.jpg", - "banner": "http://old.studentkickoff.be/sites/default/files/styles/groto_foto-980x/public/Cleymans__Van_Geel-con.jpg?itok=fl2iJ4bs", - "stage": "Main Stage" + "content": "", + "name": "Neo Minor", + "start": "2019-09-25T14:30:00+02:00", + "end": "2019-09-25T15:15:00+02:00", + "index": 2, + "description": "Op zoek naar een eigen sound en een nieuwe uitdaging vonden vier vrienden elkaar in de zomer van 2015. Neo Minor is melodische sound post-rock: gesofisticeerde pianomelodieën en melodische baslijnen ondersteund door strakke drumlijnen en zwevend engelengezang.", + "title": "Neo Minor", + "stage": "Main Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/neo.jpg" }, { - "content": "Scala beschrijft zichzelf als een indierockkoor die klassiekers en indiesongs met een twist brengt. Onderleiding van Stijn Kolacny brengt het vrouwenkoor nummers die herwerkt worden tot elegische hymnes met adembenemende effecten. Dat alles toetsen ze af met een vleugje piano. Jullie kunnen zich verwachten aan covers van Radiohead (enkele jaren geleden gingen ze nog globaal met het nummer ‘Creep’) , U2, Depeche Mode en zelfs Rammstein.", - "name": "Scala \u0026 Kolacny Brothers", - "start": "2017-09-28T21:35:00+02:00", - "end": "2017-09-28T22:55:00+02:00", - "image": "https://studentkickoff.be/assets/images/artists/scala.jpg", - "banner": "http://old.studentkickoff.be/sites/default/files/styles/groto_foto-980x/public/scala_1.jpg?itok=u1d33mlV", - "stage": "Main Stage" + "content": "", + "name": "Maxim Lany", + "index": 3, + "start": "2019-09-26T19:00:00+02:00", + "end": "2019-09-26T21:00:00+02:00", + "description": "Over the past years Maxim Lany has created his very own acclaimed sound, which not only made him a household name, but also led him to do what he is most passionate about. Full focus on creating new music and expressing himself through his unique DJ sets where he takes the audience on a musical journey. Maxim Lany is a Belgian DJ/producer and a well-known figure in the Belgian electronic music scene. Internationally, Maxim Lany has spread his sounds throughout the years all over Europe and Asia, building up a strong reputation. (He is also a yearly guest at Tomorrowland, Extrema Outdoor and WeCanDance). After having released his music on Bedrock Records, King Street Sounds,Kittball Records and WePlay House Recordings Maxim is now signed to Armada ElectronicElements and has also released on Moonbootique. His music is played by Solomun, Kölsch and Tale Of Us.", + "title": "Maxim Lany", + "stage": "Second Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/maxim.jpg" }, { - "content": "Het Gentse dj-duo Soul Shakers gaat al mee sinds 2007 en is daardoor voor velen al lang geen onbekende meer. Hun muziek combineert invloeden van traditionele Jamaicaanse reggae met een vleugje moderne UK bass. Samen met ZwartWerk (die coole jongens van het Studio Brussel EK-lied) en KD Soundsystem brachten ze de hit ‘Met Mij Mee’ uit. Ze hebben een sterke internationale tint en vooral ook een hoog dansbaarheidsniveau. Je kon Soul Shakers deze zomer al op een paar grote podia zoals Reggae Geel en Couleur Café zien en binnenkort staan ze op ons eigenste Sint-Pietersplein in Gent. Is dat alles? Helemaal niet! De Soul Shakers komen niet alleen. Niemand minder dan MC Mota zal erbij zijn. De Limburger die al verscheen op Tomorrowland, Rock Werchter, Pukkelpop en Dour, brengt jullie naar eigen zeggen met veel plezier een streepje “deep ragga flows, energetic freestyle spitting sessions and soulful singing”. De verwachtingen liggen hoog, Mr MC Mota.", - "name": "Soul Shakers ft. MC Mota", - "start": "2017-09-28T23:00:00+02:00", - "end": "2017-09-29T00:20:00+02:00", - "image": "https://studentkickoff.be/assets/images/artists/soulshakers.jpg", - "banner": "http://old.studentkickoff.be/sites/default/files/styles/groto_foto-980x/public/soulshakers.jpg?itok=pDNNF9X6", - "stage": "Main Stage" + "content": "", + "name": "Young Foxes", + "start": "2019-09-25T15:45:00+02:00", + "end": "2019-09-25T16:30:00+02:00", + "index": 3, + "description": "Het fenomeen Young Foxes bestaat uit 5 jonge vosjes wiens liefde voor muziek even groot is als hun liefde voor elkaar. We combineren verschillende muzikale stijlen in onze nummers en de focus van de band ligt op het samen creëeren van nummers die onszelf en de luisteraar doen bewegen. Stilstaan is geen optie als de vosjes losgelaten worden!", + "title": "Young Foxes", + "stage": "Main Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/young.jpg" }, { - "content": "Ook Skyve Soundsystem is deel van onze fenomenale line-up dit jaar. De jonge Antwerpse DJ en producer heeft ondertussen al heel wat afgespeeld op grote festivals zoals Tomorrowland, Rock Werchter, Pukkelpop, en Laundry Day. Skyve mag zichzelf ‘Head of Music’ noemen bij Studio Brussel, waar hij ook nog eens mixmaster is voor Gunther D, Sound of Mish Mash, Minifuif voor Maxipret en de fameuze Botsautomix-compilaties. Wees allemaal welgekomen woensdag 28 september op het Sint-Pietersplein om eens goed te DANSEN, DANSEN, DANSEN op de heerlijke deuntjes van dé mixmaster en party-dj bij uitstek.", - "name": "Skyve Soundsystem", - "start": "2017-09-29T00:25:00+02:00", - "end": "2017-09-29T01:55:00+02:00", - "image": "https://studentkickoff.be/assets/images/artists/skyve.jpg", - "banner": "http://old.studentkickoff.be/sites/default/files/styles/groto_foto-980x/public/11427172_917385908325167_2998409867762307297_n.jpg?itok=qUkHMG9y", - "stage": "Main Stage" + "content": "", + "name": "Lebawski", + "index": 4, + "start": "2019-09-25T21:00:00+02:00", + "end": "2019-09-25T00:00:00+02:00", + "description": "Lebawski is a deejay with early roots in hip hop and drum ‘n bass. As a weekly Decadance resident and founder of Moonday, he sees music as a unified language, crossing the borders between different styles and people. Having played a lot of extended sets and all nighters, Lebawski has quite some experience behind the booth for his age. So it was time for another step, and recently he founded the vinyl only label MUZI cartel, where the direction is more into minimalistic sounds and scapes. You’re in for a ride, that’s for sure. !", + "title": "Lebawski", + "stage": "Second Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/lebawski.jpg" }, { "content": "", - "name": "WOOMES", - "start": "2017-09-28T15:30:00+02:00", - "end": "2017-09-28T16:30:00+02:00", - "link": "https://www.facebook.com/djwoomes/", - "stage": "Second Stage", - "image": "https://studentkickoff.be/assets/images/artists/" + "name": "Chackie Jam", + "start": "2019-09-25T17:00:00+02:00", + "end": "2019-09-25T17:45:00+02:00", + "index": 4, + "description": "Zowat de meest catchy trip die je kan bedenken, komt van het ​synthpopcollectiefChackie Jam​. Naar eigen zeggen maken ze prettig gestoorde ​guilty pleasure popdie iedereen aan het dansen krijgt. Met 5 loepzuivere stemmen en hun ultrafunkysynthlijnen wisten ze ook het Studio Brussel-publiek te overtuigen, in januari werdenze verkozen tot winnaar van ​De Nieuwe Lichting 2018​.", + "title": "Chackie Jam", + "stage": "Main Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/Chackie Jam.jpg" }, { "content": "", - "name": "Lebawski", - "start": "2017-09-28T16:30:00+02:00", - "end": "2017-09-28T18:00:00+02:00", - "link": "https://www.facebook.com/petehowlmusic/", - "stage": "Second Stage", - "image": "https://studentkickoff.be/assets/images/artists/" + "name": "Gestapo Knallmuzik", + "start": "2019-09-25T18:15:00+02:00", + "end": "2019-09-25T19:15:00+02:00", + "index": 5, + "description": "Einen Deutsche elektrio mit verdacht fiel schamhäre in die broeche. Sind zie die anonieme bastäärdkinders von Kraftwerk oder die hitsige minaärs von Angela Merkel? Tophits zoäls ‘Schüren mit ein Schürpapier’ und ‘Twaletpapier Gescheurdt’ gehen over zerh herkenbäre unterwerpen. Leren zie die teksten marh vonbuiten, want sie zint ganz das moeite!", + "title": "Gestapo Knallmuzik", + "stage": "Main Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/gestapo.jpg" }, { "content": "", - "name": "Sir Jacobs", - "start": "2017-09-28T18:00:00+02:00", - "end": "2017-09-28T19:30:00+02:00", - "stage": "Second Stage", - "image": "https://studentkickoff.be/assets/images/artists/" + "name": "Laura Tesoro", + "start": "2019-09-25T20:00:00+02:00", + "end": "2019-09-25T21:10:00+02:00", + "index": 6, + "description": "Sinds haar deelname aan het Eurovisiesongfestival in 2016 is Laura Tesoro niet meer van de hitradio’s weg te slaan. Haar feelgood songs “What’s The Pressure”, “Higher”, “Beast” en “Mutual” vatten Laura perfect samen: aanstekelijk, energiek en funky! ", + "title": "Laura Tesoro", + "stage": "Main Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/laura.jpg" }, { "content": "", - "name": "Seba Lecompte", - "start": "2017-09-28T19:30:00+02:00", - "end": "2017-09-28T21:00:00+02:00", - "link": "https://www.facebook.com/sebalecompte", - "stage": "Second Stage", - "image": "https://studentkickoff.be/assets/images/artists/" + "name": "Ronnie Flex & Deuxperience", + "start": "2019-09-25T22:00:00+02:00", + "end": "2019-09-25T23:00:00+02:00", + "index": 7, + "description": " Ronnie Flex is de afgelopen jaren uitgegroeid tot het artistiek imponerende, boeiende en uitgesproken boegbeeld van een ongekend succesvolle generatie hiphopartiesten. De eigenzinnige, genre-overstijgende, performer heeft met zijn releases een abonnement op de hitlijsten. Samen met de band Deuxperience tourt hij sinds vorig jaar door Nederland. Met zijn eigen instrument ‘autotune’ en ondersteund door een fenomenale 9-koppige band komen zijn Caribische roots meer naar de voorgrond, en is stilstaan geen optie. Of zoals hij zelf zegt in het NRC: ‘Uiteindelijk wil ik gewoon een salsa-zanger zijn. Ik wil dat iedereen al gaat dansen zodra ik het podium op kom’. ", + "title": "Ronnie Flex & Deuxperience", + "stage": "Main Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/ronnyflex.jpg" }, { "content": "", - "name": "TRiXY", - "start": "2017-09-28T21:00:00+02:00", - "end": "2017-09-28T22:30:00+02:00", - "link": "https://www.facebook.com/TrixyLab.105db/", - "stage": "Second Stage", - "image": "https://studentkickoff.be/assets/images/artists/" + "name": "Regi", + "start": "2019-09-25T23:15:00+02:00", + "end": "2019-09-25T00:15:00+02:00", + "index": 8, + "description": "Regi DJ en podiumbeest van België! Hij verkocht al 25 keer het Sportpaleis uit en heeft al meer dan 30 top 10 hits in Vlaanderen. Na Tomorrowland en Rock Werchter staat deze glimlachende Limburger op Student Kick-Off! Zing mee met talloze hits zoals ‘Where Did You Go (Summer Loce)’ en ‘Ellie’, een feel-good track opgedragen aan zijn oudste dochter Ellie Martha. En ja, we blijven het zeggen (sorry Regi): ‘waar zijn die handjes!’ ", + "title": "Regi", + "stage": "Main Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/regi.jpg" }, { "content": "", - "name": "Pete Howl", - "start": "2017-09-28T22:30:00+02:00", - "end": "2017-09-28T00:00:00+02:00", - "link": "https://www.facebook.com/petehowlmusic/", - "stage": "Second Stage", - "image": "https://studentkickoff.be/assets/images/artists/" + "name": "5NAPBACK", + "start": "2019-09-25T00:20:00+02:00", + "end": "2019-09-25T01:50:00+02:00", + "index": 9, + "description": "5NAPBACK schopte het in juli 2016 tot winnaar van België’s grootste dj contest ‘MNM Start to DJ’! Hierdoor kwam hij terecht in het voorprogramma van Dimitri Vegas & Like Mike. Door zijn snelle mixstijl en eigen edits passeerde hij reeds Tomorrowland, Ushuaïa, Ibiza en veel meer. Ook verzorgde hij al afbraakwerken in zo wat alle uithoeken van België. 5napback sluit het Sint-Pietersplein af met een mix van de beste commerciële schijven in combinatie met ongelooflijke ‘alles kapot’ platen. ", + "title": "5NAPBACK", + "stage": "Main Stage", + "image": "https://studentkickoff.be/assets/images/artists/2019/5napback.jpg" } -] +] \ No newline at end of file From 115296723f2948e6d9b725ae186c1c59aea2e0ac Mon Sep 17 00:00:00 2001 From: Niko Strijbol Date: Thu, 19 Sep 2019 13:11:33 +0200 Subject: [PATCH 2/7] Add button for privacy policy --- .../ui/customtabs/CustomTabsHelper.java | 51 +++++++++++-------- .../ui/customtabs/HasTabActivityHelper.java | 6 +-- .../hydra/onboarding/ReportingFragment.java | 7 +++ .../layout/fragment_onboarding_reporting.xml | 20 ++++++++ app/src/main/res/values-en/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + 6 files changed, 63 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/be/ugent/zeus/hydra/common/ui/customtabs/CustomTabsHelper.java b/app/src/main/java/be/ugent/zeus/hydra/common/ui/customtabs/CustomTabsHelper.java index 75d561f3f..507d650e0 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/common/ui/customtabs/CustomTabsHelper.java +++ b/app/src/main/java/be/ugent/zeus/hydra/common/ui/customtabs/CustomTabsHelper.java @@ -7,14 +7,19 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; -import androidx.annotation.Nullable; -import androidx.browser.customtabs.CustomTabsService; import android.text.TextUtils; import android.util.Log; +import androidx.annotation.Nullable; +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.browser.customtabs.CustomTabsService; + import java.util.ArrayList; import java.util.List; +import be.ugent.zeus.hydra.R; +import be.ugent.zeus.hydra.utils.NetworkUtils; + /** * Helper for custom tabs. * @@ -44,7 +49,7 @@ public class CustomTabsHelper { * @param context {@link Context} to use for accessing {@link PackageManager}. * @return The package name recommended to use for connecting to custom tabs related components. */ - public static String getPackageNameToUse(Context context) { + static String getPackageNameToUse(Context context) { if (packageNameToUse != null) { return packageNameToUse; @@ -122,21 +127,8 @@ private static boolean hasSpecializedHandlerIntents(Context context, Intent inte return false; } - protected static boolean hasSupport(Activity activity) { - return CustomTabsHelper.getPackageNameToUse(activity) != null; - } - - /** - * Get an activity helper. When custom tabs are supported, it will use those. If custom tabs are not supported, - * it will open urls in a new browser window. - * - * @param activity The activity that calls the custom tab. - * @param callback The callback. - * - * @return The helper. - */ - public static ActivityHelper initHelper(Activity activity, @Nullable ActivityHelper.ConnectionCallback callback) { - return initHelper(activity, true, callback); + private static boolean hasSupport(Context context) { + return CustomTabsHelper.getPackageNameToUse(context) != null; } /** @@ -145,16 +137,33 @@ public static ActivityHelper initHelper(Activity activity, @Nullable ActivityHel * an app is available that can handle a certain url. A normal intent will be launched then. * * @param activity The activity that calls the custom tab. - * @param nativeApp If the native app should be used if available. * @param callback The callback. * * @return The helper. */ - public static ActivityHelper initHelper(Activity activity, boolean nativeApp, @Nullable ActivityHelper.ConnectionCallback callback) { + public static ActivityHelper initHelper(Activity activity, @Nullable ActivityHelper.ConnectionCallback callback) { if(hasSupport(activity)) { - return new HasTabActivityHelper(activity, nativeApp, callback); + return new HasTabActivityHelper(activity, callback); } else { return new NoTabActivityHelper(activity, callback); } } + + /** + * Open an URI in a Custom Tab if supported. Otherwise, an attempt is made to open a browser. + * + * @param context Context to use. + * @param uri The URI to open. + */ + public static void openUri(Context context, Uri uri) { + if (hasSupport(context)) { + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + //noinspection deprecation + builder.setToolbarColor(context.getResources().getColor(R.color.hydra_primary_color)); + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.launchUrl(context, uri); + } else { + NetworkUtils.maybeLaunchBrowser(context, uri.toString()); + } + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/zeus/hydra/common/ui/customtabs/HasTabActivityHelper.java b/app/src/main/java/be/ugent/zeus/hydra/common/ui/customtabs/HasTabActivityHelper.java index 0ffcee152..285760205 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/common/ui/customtabs/HasTabActivityHelper.java +++ b/app/src/main/java/be/ugent/zeus/hydra/common/ui/customtabs/HasTabActivityHelper.java @@ -32,7 +32,6 @@ class HasTabActivityHelper implements ActivityHelper { private final ConnectionCallback connectionCallback; private final WeakReference activity; - private final boolean nativeApp; private boolean showShareMenu; private int intentFlags; @@ -45,10 +44,9 @@ class HasTabActivityHelper implements ActivityHelper { /** * Package local constructor. */ - HasTabActivityHelper(Activity activity, boolean nativeApp, @Nullable ConnectionCallback connectionCallback) { + HasTabActivityHelper(Activity activity, @Nullable ConnectionCallback connectionCallback) { this.activity = new WeakReference<>(activity); this.connectionCallback = connectionCallback; - this.nativeApp = nativeApp; } @Override @@ -74,7 +72,7 @@ public void openCustomTab(Uri uri) { builder.setToolbarColor(ViewUtils.getPrimaryColor(activity.get())); Set nat = getNativeAppPackage(activity.get(), uri); - if (nativeApp && !nat.isEmpty()) { + if (!nat.isEmpty()) { Log.d(TAG, "Using normal intent because of native app, i.e. " + nat.iterator().next()); Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri); browserIntent.setFlags(this.intentFlags); diff --git a/app/src/main/java/be/ugent/zeus/hydra/onboarding/ReportingFragment.java b/app/src/main/java/be/ugent/zeus/hydra/onboarding/ReportingFragment.java index caacfb9e4..2e60a0a54 100644 --- a/app/src/main/java/be/ugent/zeus/hydra/onboarding/ReportingFragment.java +++ b/app/src/main/java/be/ugent/zeus/hydra/onboarding/ReportingFragment.java @@ -1,5 +1,6 @@ package be.ugent.zeus.hydra.onboarding; +import android.net.Uri; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -14,6 +15,9 @@ import be.ugent.zeus.hydra.R; import be.ugent.zeus.hydra.common.reporting.Reporting; +import be.ugent.zeus.hydra.common.ui.customtabs.ActivityHelper; +import be.ugent.zeus.hydra.common.ui.customtabs.CustomTabsHelper; +import be.ugent.zeus.hydra.utils.NetworkUtils; import com.heinrichreimersoftware.materialintro.app.SlideFragment; import static androidx.core.view.ViewCompat.requireViewById; @@ -23,6 +27,8 @@ */ public class ReportingFragment extends SlideFragment { + private static final String PRIVACY_POLICY = "https://hydra.ugent.be/privacy-policy.html"; + private RadioGroup analyticsChooser; private Switch crashReportingChooser; @@ -40,6 +46,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat addOnNavigationBlockedListener((position, direction) -> Toast.makeText(requireContext().getApplicationContext(), R.string.onboarding_reporting_required, Toast.LENGTH_SHORT) .show()); + requireViewById(view, R.id.read_policy).setOnClickListener(v -> CustomTabsHelper.openUri(v.getContext(), Uri.parse(PRIVACY_POLICY))); } @Override diff --git a/app/src/main/res/layout/fragment_onboarding_reporting.xml b/app/src/main/res/layout/fragment_onboarding_reporting.xml index fdedc4b9b..8fb04753a 100644 --- a/app/src/main/res/layout/fragment_onboarding_reporting.xml +++ b/app/src/main/res/layout/fragment_onboarding_reporting.xml @@ -99,4 +99,24 @@ android:checked="true" android:text="@string/onboarding_reporting_allow_crash" /> + + +