From 1a7b68c2d8165784ed33080538bfe14cec17f744 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Wed, 13 Dec 2017 21:08:10 -0500 Subject: [PATCH 01/41] WIP --- .../data/models/VehicleDetails.java | 208 ------------------ .../models/{ => launchlibrary}/Agency.java | 2 +- .../models/{ => launchlibrary}/Family.java | 2 +- .../data/models/{ => launchlibrary}/LSP.java | 2 +- .../models/{ => launchlibrary}/Launch.java | 4 +- .../{ => launchlibrary}/LaunchMini.java | 2 +- .../models/{ => launchlibrary}/Launcher.java | 2 +- .../models/{ => launchlibrary}/Location.java | 2 +- .../models/{ => launchlibrary}/Mission.java | 2 +- .../data/models/{ => launchlibrary}/Pad.java | 2 +- .../models/{ => launchlibrary}/Rocket.java | 2 +- .../{ => launchlibrary}/RocketFamily.java | 2 +- .../data/models/spacelaunchnow/Agency.java | 70 ++++++ .../models/{ => spacelaunchnow}/Orbiter.java | 2 +- .../{ => spacelaunchnow}/RocketDetail.java | 4 +- .../data/networking/DataClient.java | 6 +- .../data/networking/DataClientThreaded.java | 2 +- .../interfaces/SpaceLaunchNowService.java | 6 +- .../responses/base/LauncherResponse.java | 7 +- .../responses/base/OrbiterResponse.java | 2 +- .../responses/base/VehicleResponse.java | 2 +- .../launchlibrary/AgencyResponse.java | 2 +- .../launchlibrary/LaunchResponse.java | 2 +- .../launchlibrary/LocationResponse.java | 2 +- .../launchlibrary/MissionResponse.java | 2 +- .../responses/launchlibrary/PadResponse.java | 2 +- .../launchlibrary/RocketFamilyResponse.java | 2 +- .../launchlibrary/RocketResponse.java | 2 +- .../calendar/CalendarSyncManager.java | 4 +- .../calendar/CalendarUtility.java | 2 +- .../content/data/DataClientManager.java | 9 +- .../content/data/DataRepository.java | 6 +- .../content/data/DataRepositoryManager.java | 4 +- .../content/data/DataSaver.java | 5 +- .../content/events/LaunchEvent.java | 2 +- .../content/events/LaunchRequestEvent.java | 2 - .../spacelaunchnow/content/jobs/SyncJob.java | 2 - .../notifications/NotificationBuilder.java | 3 +- .../notifications/NotificationReceiver.java | 7 +- .../content/util/QueryBuilder.java | 2 +- .../content/wear/WearWatchfaceManager.java | 4 +- .../ui/debug/DebugPresenter.java | 2 +- .../ui/launchdetail/TabsAdapter.java | 1 - .../activity/LaunchDetailActivity.java | 4 +- .../fragments/AgencyDetailFragment.java | 3 +- .../fragments/MissionDetailFragment.java | 6 +- .../fragments/SummaryDetailFragment.java | 6 +- .../ui/launcher/LauncherDetailActivity.java | 8 +- .../ui/launcher/VehicleDetailAdapter.java | 4 +- .../ui/main/launches/ListAdapter.java | 2 +- .../launches/PreviousLaunchesFragment.java | 2 +- .../launches/UpcomingLaunchesFragment.java | 2 +- .../ui/main/missions/MissionAdapter.java | 2 +- .../ui/main/missions/MissionFragment.java | 2 +- .../ui/main/next/CardBigAdapter.java | 4 +- .../ui/main/next/CardSmallAdapter.java | 2 +- .../ui/main/next/NextLaunchFragment.java | 13 +- .../vehicles/launcher/LauncherFragment.java | 4 +- .../vehicles/launcher/VehicleAdapter.java | 6 +- .../main/vehicles/orbiter/OrbiterAdapter.java | 3 +- .../vehicles/orbiter/OrbiterFragment.java | 2 +- .../ui/orbiter/OrbiterDetailActivity.java | 2 +- .../fragments/NotificationsFragment.java | 2 +- .../spacelaunchnow/utils/Utils.java | 7 +- .../launchcard/LaunchCardCompactManager.java | 2 +- .../launchcard/UpdateLaunchCardJob.java | 21 -- .../wordtimer/LaunchWordTimerManager.java | 3 +- .../widget/wordtimer/UpdateWordTimerJob.java | 24 -- mobile/version.properties | 4 +- wear/version.properties | 4 +- 70 files changed, 159 insertions(+), 387 deletions(-) delete mode 100644 data/src/main/java/me/calebjones/spacelaunchnow/data/models/VehicleDetails.java rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/Agency.java (95%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/Family.java (90%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/LSP.java (95%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/Launch.java (98%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/LaunchMini.java (94%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/Launcher.java (91%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/Location.java (93%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/Mission.java (95%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/Pad.java (96%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/Rocket.java (96%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => launchlibrary}/RocketFamily.java (95%) create mode 100644 data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Agency.java rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => spacelaunchnow}/Orbiter.java (94%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{ => spacelaunchnow}/RocketDetail.java (98%) diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/VehicleDetails.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/VehicleDetails.java deleted file mode 100644 index be7d28e8a..000000000 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/VehicleDetails.java +++ /dev/null @@ -1,208 +0,0 @@ -package me.calebjones.spacelaunchnow.data.models; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -public class VehicleDetails implements Serializable { - - private String LVName; - private String LVFamily; - private String LVSFamily; - private String LVManufacturer; - private String LVVariant; - private String LVAlias; - private String Description; - private Integer MinStage; - private Integer MaxStage; - private String Length; - private String Diameter; - private String LaunchMass; - private String LEOCapacity; - private String GTOCapacity; - private String TOThrust; - private String Class; - private String Apogee; - private String ImageURL; - private String Range; - private String InfoURL; - private String WikiURL; - private Map additionalProperties = new HashMap(); - - public String getInfoURL() { - return InfoURL; - } - - public void setInfoURL(String InfoURL) { - this.InfoURL = InfoURL; - } - - public String getWikiURL() { - return WikiURL; - } - - public void setWikiURL(String WikiURL) { - this.WikiURL = WikiURL; - } - - public String getLVName() { - return LVName; - } - - public void setLVName(String LVName) { - this.LVName = LVName; - } - - public String getLVFamily() { - return LVFamily; - } - - public void setLVFamily(String LVFamily) { - this.LVFamily = LVFamily; - } - - public String getLVSFamily() { - return LVSFamily; - } - - public void setLVSFamily(String LVSFamily) { - this.LVSFamily = LVSFamily; - } - - public String getLVManufacturer() { - return LVManufacturer; - } - - public void setLVManufacturer(String LVManufacturer) { - this.LVManufacturer = LVManufacturer; - } - - public String getLVVariant() { - return LVVariant; - } - - public void setLVVariant(String LVVariant) { - this.LVVariant = LVVariant; - } - - public String getLVAlias() { - return LVAlias; - } - - public void setLVAlias(String LVAlias) { - this.LVAlias = LVAlias; - } - - public Integer getMinStage() { - return MinStage; - } - - public void setMinStage(Integer MinStage) { - this.MinStage = MinStage; - } - - public Integer getMaxStage() { - return MaxStage; - } - - public void setMaxStage(Integer MaxStage) { - this.MaxStage = MaxStage; - } - - public String getLength() { - return Length; - } - - public void setLength(String Length) { - this.Length = Length; - } - - public String getDiameter() { - return Diameter; - } - - public void setDiameter(String Diameter) { - this.Diameter = Diameter; - } - - public String getLaunchMass() { - return LaunchMass; - } - - public void setLaunchMass(String LaunchMass) { - this.LaunchMass = LaunchMass; - } - - public String getLEOCapacity() { - return LEOCapacity; - } - - public void setLEOCapacity(String LEOCapacity) { - this.LEOCapacity = LEOCapacity; - } - - public String getGTOCapacity() { - return GTOCapacity; - } - - public void setGTOCapacity(String GTOCapacity) { - this.GTOCapacity = GTOCapacity; - } - - public String getTOThrust() { - return TOThrust; - } - - public void setTOThrust(String TOThrust) { - this.TOThrust = TOThrust; - } - - public String getClass_() { - return Class; - } - - public void setClass_(String Class) { - this.Class = Class; - } - - public String getApogee() { - return Apogee; - } - - public void setDescription(String Description) { - this.Description = Description; - } - - public String getDescription() { - return Description; - } - - public void setApogee(String Apogee) { - this.Apogee = Apogee; - } - - public String getRange() { - return Range; - } - - public void setRange(String Range) { - this.Range = Range; - } - - public String getImageURL() { - return ImageURL; - } - - public void setImageURL(String ImageURL) { - this.ImageURL = ImageURL; - } - - public Map getAdditionalProperties() { - return this.additionalProperties; - } - - public void setAdditionalProperty(String name, Object value) { - this.additionalProperties.put(name, value); - } - -} diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Agency.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Agency.java similarity index 95% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/Agency.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Agency.java index ea3be495d..04e320be1 100755 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Agency.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Agency.java @@ -1,5 +1,5 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import io.realm.RealmObject; import io.realm.annotations.PrimaryKey; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Family.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Family.java similarity index 90% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/Family.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Family.java index fbd651943..2b1a62291 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Family.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Family.java @@ -1,4 +1,4 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import io.realm.RealmObject; import io.realm.annotations.PrimaryKey; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/LSP.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/LSP.java similarity index 95% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/LSP.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/LSP.java index 6f37aee2d..943e6c67b 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/LSP.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/LSP.java @@ -1,4 +1,4 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import io.realm.RealmObject; import io.realm.annotations.PrimaryKey; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Launch.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launch.java similarity index 98% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/Launch.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launch.java index f1867f45e..9562938e3 100755 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Launch.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launch.java @@ -1,7 +1,5 @@ -package me.calebjones.spacelaunchnow.data.models; - -import com.google.gson.annotations.SerializedName; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import java.util.Date; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/LaunchMini.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/LaunchMini.java similarity index 94% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/LaunchMini.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/LaunchMini.java index 206ae3fb6..929df80cb 100755 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/LaunchMini.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/LaunchMini.java @@ -1,5 +1,5 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import java.util.Date; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Launcher.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launcher.java similarity index 91% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/Launcher.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launcher.java index 16d4c268a..f708e52d1 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Launcher.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launcher.java @@ -1,4 +1,4 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import com.google.gson.annotations.SerializedName; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Location.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Location.java similarity index 93% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/Location.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Location.java index 1e30bcf2a..2703b9deb 100755 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Location.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Location.java @@ -1,5 +1,5 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import io.realm.RealmList; import io.realm.RealmObject; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Mission.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Mission.java similarity index 95% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/Mission.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Mission.java index 2442798c1..19db8baaa 100755 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Mission.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Mission.java @@ -1,5 +1,5 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import io.realm.RealmObject; import io.realm.annotations.PrimaryKey; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Pad.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Pad.java similarity index 96% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/Pad.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Pad.java index 5ce720b3f..2c7305514 100755 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Pad.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Pad.java @@ -1,5 +1,5 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import io.realm.RealmList; import io.realm.RealmObject; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Rocket.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Rocket.java similarity index 96% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/Rocket.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Rocket.java index 6fbdaadd8..4bf0ab29f 100755 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Rocket.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Rocket.java @@ -1,5 +1,5 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import io.realm.RealmList; import io.realm.RealmObject; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/RocketFamily.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/RocketFamily.java similarity index 95% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/RocketFamily.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/RocketFamily.java index 0a9473453..92e86bdb1 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/RocketFamily.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/RocketFamily.java @@ -1,4 +1,4 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.launchlibrary; import io.realm.RealmList; import io.realm.RealmObject; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Agency.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Agency.java new file mode 100644 index 000000000..df2181418 --- /dev/null +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Agency.java @@ -0,0 +1,70 @@ +package me.calebjones.spacelaunchnow.data.models.spacelaunchnow; + +import com.google.gson.annotations.SerializedName; +import io.realm.RealmObject; + +public class Agency extends RealmObject{ + + @SerializedName(value = "agency") + String agency; + @SerializedName(value = "launchers") + String launchers; + @SerializedName(value = "orbiters") + String orbiters; + @SerializedName(value = "description") + String description; + @SerializedName(value = "image_url") + String imageURL; + @SerializedName(value = "nation_url") + String nationURL; + + public String getAgency() { + return agency; + } + + public void setAgency(String agency) { + this.agency = agency; + } + + public String getLaunchers() { + return launchers; + } + + public void setLaunchers(String launchers) { + this.launchers = launchers; + } + + public String getOrbiters() { + return orbiters; + } + + public void setOrbiters(String orbiters) { + this.orbiters = orbiters; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getImageURL() { + return imageURL; + } + + public void setImageURL(String imageURL) { + this.imageURL = imageURL; + } + + public String getNationURL() { + return nationURL; + } + + public void setNationURL(String nationURL) { + this.nationURL = nationURL; + } + + +} diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Orbiter.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Orbiter.java similarity index 94% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/Orbiter.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Orbiter.java index b12a794c5..53ef330fb 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Orbiter.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Orbiter.java @@ -1,4 +1,4 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.spacelaunchnow; import com.google.gson.annotations.SerializedName; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/RocketDetail.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java similarity index 98% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/RocketDetail.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java index fc0968579..43f5e4dc2 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/RocketDetail.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java @@ -1,4 +1,4 @@ -package me.calebjones.spacelaunchnow.data.models; +package me.calebjones.spacelaunchnow.data.models.spacelaunchnow; import com.google.gson.annotations.SerializedName; @@ -22,7 +22,7 @@ public class RocketDetail extends RealmObject { private String family; @SerializedName(value = "s_family") private String sFamily; - @SerializedName(value = "manufacturer") + @SerializedName(value = "agency") private String manufacturer; @SerializedName(value = "variant") private String variant; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/DataClient.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/DataClient.java index 599618dd1..90e399910 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/DataClient.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/DataClient.java @@ -3,7 +3,7 @@ import java.io.IOException; import me.calebjones.spacelaunchnow.data.helpers.Utils; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.networking.interfaces.LibraryService; import me.calebjones.spacelaunchnow.data.networking.interfaces.SpaceLaunchNowService; import me.calebjones.spacelaunchnow.data.networking.responses.base.VehicleResponse; @@ -204,8 +204,8 @@ public Call getPadsByID(int padID, Callback callback) return call; } - public Call getVehicles(String family, Callback callback) { - Call call = spaceLaunchNowService.getVehicles(family); + public Call getVehicles(String agency, Callback callback) { + Call call = spaceLaunchNowService.getVehicles(agency); call.enqueue(callback); diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/DataClientThreaded.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/DataClientThreaded.java index aad758103..e365b353b 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/DataClientThreaded.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/DataClientThreaded.java @@ -3,7 +3,7 @@ import java.io.IOException; import me.calebjones.spacelaunchnow.data.helpers.Utils; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.networking.interfaces.LibraryService; import me.calebjones.spacelaunchnow.data.networking.interfaces.SpaceLaunchNowService; import me.calebjones.spacelaunchnow.data.networking.responses.base.VehicleResponse; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/SpaceLaunchNowService.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/SpaceLaunchNowService.java index d06c13df2..db10fed10 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/SpaceLaunchNowService.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/SpaceLaunchNowService.java @@ -21,10 +21,10 @@ public interface SpaceLaunchNowService { @Headers({ "User-Agent: SpaceLaunchNow-" + BuildConfig.VERSION_NAME }) - @GET(version + "/launchers/") - Call getLaunchers(); + @GET(version + "/agency/") + Call getAgencies(); @Headers({"User-Agent: SpaceLaunchNow-" + BuildConfig.VERSION_NAME}) @GET(version + "/launcher_details/") - Call getVehicles(@Query("family") String family); + Call getVehicles(@Query("launch_agency__agency") String agency); } diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/LauncherResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/LauncherResponse.java index 184fae3d7..8846b9ed9 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/LauncherResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/LauncherResponse.java @@ -2,13 +2,14 @@ import com.google.gson.annotations.SerializedName; -import me.calebjones.spacelaunchnow.data.models.Launcher; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launcher; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.Agency; public class LauncherResponse { @SerializedName(value="results") - private Launcher[] launchers; + private Agency[] launchers; - public Launcher[] getLaunchers() { + public Agency[] getLaunchers() { return launchers; } } diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/OrbiterResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/OrbiterResponse.java index b88a6942d..4ed3d5b1c 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/OrbiterResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/OrbiterResponse.java @@ -2,7 +2,7 @@ import com.google.gson.annotations.SerializedName; -import me.calebjones.spacelaunchnow.data.models.Orbiter; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.Orbiter; public class OrbiterResponse { @SerializedName(value="results") diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/VehicleResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/VehicleResponse.java index 33a016165..46ed1935e 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/VehicleResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/VehicleResponse.java @@ -2,7 +2,7 @@ import com.google.gson.annotations.SerializedName; -import me.calebjones.spacelaunchnow.data.models.RocketDetail; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; public class VehicleResponse { diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/AgencyResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/AgencyResponse.java index f67413bbf..b99705eeb 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/AgencyResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/AgencyResponse.java @@ -1,6 +1,6 @@ package me.calebjones.spacelaunchnow.data.networking.responses.launchlibrary; -import me.calebjones.spacelaunchnow.data.models.Agency; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Agency; public class AgencyResponse extends BaseResponse { private Agency[] agencies; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/LaunchResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/LaunchResponse.java index d9d57b14b..2682ffdf2 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/LaunchResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/LaunchResponse.java @@ -1,6 +1,6 @@ package me.calebjones.spacelaunchnow.data.networking.responses.launchlibrary; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; public class LaunchResponse extends BaseResponse { private Launch[] launches; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/LocationResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/LocationResponse.java index 37a3796b2..509aac19a 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/LocationResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/LocationResponse.java @@ -1,6 +1,6 @@ package me.calebjones.spacelaunchnow.data.networking.responses.launchlibrary; -import me.calebjones.spacelaunchnow.data.models.Location; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Location; public class LocationResponse extends BaseResponse{ private Location[] locations; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/MissionResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/MissionResponse.java index 7054aa102..a3196d70f 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/MissionResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/MissionResponse.java @@ -1,6 +1,6 @@ package me.calebjones.spacelaunchnow.data.networking.responses.launchlibrary; -import me.calebjones.spacelaunchnow.data.models.Mission; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Mission; public class MissionResponse extends BaseResponse { private Mission[] missions; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/PadResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/PadResponse.java index 6015aded0..161ba04d3 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/PadResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/PadResponse.java @@ -1,6 +1,6 @@ package me.calebjones.spacelaunchnow.data.networking.responses.launchlibrary; -import me.calebjones.spacelaunchnow.data.models.Pad; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Pad; public class PadResponse extends BaseResponse{ private Pad[] pads; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/RocketFamilyResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/RocketFamilyResponse.java index 2ddd458e8..d477b1699 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/RocketFamilyResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/RocketFamilyResponse.java @@ -1,6 +1,6 @@ package me.calebjones.spacelaunchnow.data.networking.responses.launchlibrary; -import me.calebjones.spacelaunchnow.data.models.RocketFamily; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.RocketFamily; public class RocketFamilyResponse extends BaseResponse { private RocketFamily[] RocketFamilies; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/RocketResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/RocketResponse.java index 76ac2f9f0..699b4daa4 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/RocketResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/launchlibrary/RocketResponse.java @@ -1,6 +1,6 @@ package me.calebjones.spacelaunchnow.data.networking.responses.launchlibrary; -import me.calebjones.spacelaunchnow.data.models.Rocket; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Rocket; public class RocketResponse extends BaseResponse { private Rocket[] rockets; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/calendar/CalendarSyncManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/calendar/CalendarSyncManager.java index 2818c029b..900b1a864 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/calendar/CalendarSyncManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/calendar/CalendarSyncManager.java @@ -1,7 +1,6 @@ package me.calebjones.spacelaunchnow.calendar; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.provider.CalendarContract; @@ -10,9 +9,8 @@ import io.realm.RealmList; import io.realm.RealmResults; import me.calebjones.spacelaunchnow.calendar.model.CalendarItem; -import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.services.BaseManager; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.content.util.QueryBuilder; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/calendar/CalendarUtility.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/calendar/CalendarUtility.java index 18c8c7ac1..cc95ca433 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/calendar/CalendarUtility.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/calendar/CalendarUtility.java @@ -28,7 +28,7 @@ import me.calebjones.spacelaunchnow.calendar.model.Calendar; import me.calebjones.spacelaunchnow.calendar.model.CalendarItem; import me.calebjones.spacelaunchnow.calendar.model.Event; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import timber.log.Timber; // these imports are used in the following code diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataClientManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataClientManager.java index 03cc32562..63773bcbf 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataClientManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataClientManager.java @@ -4,19 +4,14 @@ import com.crashlytics.android.Crashlytics; -import java.util.ArrayList; -import java.util.Arrays; - import io.realm.RealmList; -import io.realm.RealmResults; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.services.NextLaunchTracker; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.models.Result; -import me.calebjones.spacelaunchnow.data.models.RocketDetail; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.data.networking.DataClient; -import me.calebjones.spacelaunchnow.data.networking.DataClientThreaded; import me.calebjones.spacelaunchnow.data.networking.error.ErrorUtil; import me.calebjones.spacelaunchnow.data.networking.responses.base.VehicleResponse; import me.calebjones.spacelaunchnow.data.networking.responses.launchlibrary.AgencyResponse; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataRepository.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataRepository.java index e790e1b28..fa39a6055 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataRepository.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataRepository.java @@ -11,9 +11,9 @@ import io.realm.RealmResults; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.util.QueryBuilder; -import me.calebjones.spacelaunchnow.data.models.Launch; -import me.calebjones.spacelaunchnow.data.models.Location; -import me.calebjones.spacelaunchnow.data.models.Mission; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Location; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Mission; import timber.log.Timber; /** diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataRepositoryManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataRepositoryManager.java index 00650348b..e4c6becf3 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataRepositoryManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataRepositoryManager.java @@ -1,7 +1,6 @@ package me.calebjones.spacelaunchnow.content.data; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; @@ -10,9 +9,8 @@ import io.realm.Realm; import io.realm.RealmResults; -import me.calebjones.spacelaunchnow.content.services.LibraryDataManager; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.models.UpdateRecord; import me.calebjones.spacelaunchnow.utils.Connectivity; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataSaver.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataSaver.java index d232e450f..326bf13b1 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataSaver.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataSaver.java @@ -5,7 +5,6 @@ import com.crashlytics.android.Crashlytics; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; @@ -17,9 +16,9 @@ import io.realm.Sort; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.util.QueryBuilder; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.models.LaunchNotification; -import me.calebjones.spacelaunchnow.data.models.Mission; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Mission; import me.calebjones.spacelaunchnow.data.models.Result; import me.calebjones.spacelaunchnow.data.models.UpdateRecord; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/events/LaunchEvent.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/events/LaunchEvent.java index ad98d57d4..7302cc776 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/events/LaunchEvent.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/events/LaunchEvent.java @@ -1,6 +1,6 @@ package me.calebjones.spacelaunchnow.content.events; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; public class LaunchEvent { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/events/LaunchRequestEvent.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/events/LaunchRequestEvent.java index 0d4101be6..1707520a6 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/events/LaunchRequestEvent.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/events/LaunchRequestEvent.java @@ -1,7 +1,5 @@ package me.calebjones.spacelaunchnow.content.events; -import me.calebjones.spacelaunchnow.data.models.Launch; - /** * Created by Caleb on 11/16/2017. */ diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/jobs/SyncJob.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/jobs/SyncJob.java index e83de2a5a..6341943ba 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/jobs/SyncJob.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/jobs/SyncJob.java @@ -12,10 +12,8 @@ import io.realm.Realm; import io.realm.RealmConfiguration; -import io.realm.RealmResults; import me.calebjones.spacelaunchnow.content.data.DataClientManager; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Launch; import timber.log.Timber; public class SyncJob extends Job { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/notifications/NotificationBuilder.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/notifications/NotificationBuilder.java index ed9e6fbe4..49357856c 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/notifications/NotificationBuilder.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/notifications/NotificationBuilder.java @@ -19,9 +19,8 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; -import me.calebjones.spacelaunchnow.ui.main.MainActivity; import me.calebjones.spacelaunchnow.utils.Utils; import static me.calebjones.spacelaunchnow.content.notifications.NotificationHelper.CHANNEL_LAUNCH_IMMINENT; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/notifications/NotificationReceiver.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/notifications/NotificationReceiver.java index 1be299285..d2ac79a61 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/notifications/NotificationReceiver.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/notifications/NotificationReceiver.java @@ -16,10 +16,9 @@ import java.util.Locale; import me.calebjones.spacelaunchnow.BuildConfig; -import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; -import me.calebjones.spacelaunchnow.data.models.Launch; -import me.calebjones.spacelaunchnow.data.models.Location; -import me.calebjones.spacelaunchnow.data.models.Rocket; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Location; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Rocket; import me.calebjones.spacelaunchnow.utils.Utils; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java index be40c5ba7..88024da5d 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java @@ -17,7 +17,7 @@ import io.realm.Sort; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import timber.log.Timber; public class QueryBuilder { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/wear/WearWatchfaceManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/wear/WearWatchfaceManager.java index c07c7b6f5..11c7d775f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/wear/WearWatchfaceManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/wear/WearWatchfaceManager.java @@ -27,8 +27,8 @@ import jp.wasabeef.glide.transformations.gpu.BrightnessFilterTransformation; import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.services.BaseManager; -import me.calebjones.spacelaunchnow.data.models.Launch; -import me.calebjones.spacelaunchnow.data.models.RocketDetail; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.transformations.SaturationTransformation; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/debug/DebugPresenter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/debug/DebugPresenter.java index e1c25a63b..90d8f53bb 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/debug/DebugPresenter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/debug/DebugPresenter.java @@ -21,7 +21,7 @@ import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.jobs.JobUtils; import me.calebjones.spacelaunchnow.content.services.LibraryDataManager; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.models.Products; import me.calebjones.spacelaunchnow.data.networking.DataClient; import me.calebjones.spacelaunchnow.ui.supporter.SupporterHelper; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/TabsAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/TabsAdapter.java index 85d3f79f1..3a69e5b52 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/TabsAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/TabsAdapter.java @@ -4,7 +4,6 @@ import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; -import me.calebjones.spacelaunchnow.data.models.Launch; import me.calebjones.spacelaunchnow.ui.launchdetail.fragments.AgencyDetailFragment; import me.calebjones.spacelaunchnow.ui.launchdetail.fragments.MissionDetailFragment; import me.calebjones.spacelaunchnow.ui.launchdetail.fragments.SummaryDetailFragment; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java index cee18a6bb..b41329ba4 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java @@ -45,8 +45,8 @@ import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.events.LaunchEvent; import me.calebjones.spacelaunchnow.content.events.LaunchRequestEvent; -import me.calebjones.spacelaunchnow.data.models.Launch; -import me.calebjones.spacelaunchnow.data.models.RocketDetail; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.data.networking.DataClient; import me.calebjones.spacelaunchnow.data.networking.responses.launchlibrary.LaunchResponse; import me.calebjones.spacelaunchnow.ui.launchdetail.TabsAdapter; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java index 6b3a1a6e8..8182a2569 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java @@ -24,7 +24,7 @@ import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.events.LaunchEvent; import me.calebjones.spacelaunchnow.data.models.VehicleDetails; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.Utils; @@ -37,7 +37,6 @@ public class AgencyDetailFragment extends BaseFragment { private Context context; public static Launch detailLaunch; - private VehicleDetails launchVehicle; @BindView(R.id.mission_one) LinearLayout mission_one; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java index d2bd069ef..d85b93a21 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java @@ -22,9 +22,9 @@ import me.calebjones.spacelaunchnow.common.BaseFragment; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.events.LaunchEvent; -import me.calebjones.spacelaunchnow.data.models.Launch; -import me.calebjones.spacelaunchnow.data.models.Mission; -import me.calebjones.spacelaunchnow.data.models.RocketDetail; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Mission; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.Utils; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java index 78e788bb1..8b20cd37d 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java @@ -56,9 +56,9 @@ import me.calebjones.spacelaunchnow.content.events.LaunchEvent; import me.calebjones.spacelaunchnow.content.services.LibraryDataManager; import me.calebjones.spacelaunchnow.content.util.DialogAdapter; -import me.calebjones.spacelaunchnow.data.models.Launch; -import me.calebjones.spacelaunchnow.data.models.Pad; -import me.calebjones.spacelaunchnow.data.models.RocketDetail; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Pad; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.data.models.realm.RealmStr; import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.Utils; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java index ed7543970..3fee01b8b 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java @@ -32,8 +32,8 @@ import me.calebjones.spacelaunchnow.common.BaseActivity; import me.calebjones.spacelaunchnow.content.data.DataSaver; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.Launcher; -import me.calebjones.spacelaunchnow.data.models.RocketDetail; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launcher; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.data.networking.DataClient; import me.calebjones.spacelaunchnow.data.networking.responses.base.VehicleResponse; import me.calebjones.spacelaunchnow.ui.main.MainActivity; @@ -182,14 +182,14 @@ public void displayRockets() { detail_rocket.setText(name); detail_vehicle_agency.setText(agency); - rocketLaunches = getRealm().where(RocketDetail.class).contains("family", name).findAll(); + rocketLaunches = getRealm().where(RocketDetail.class).contains("manufacturer", agency).findAll(); if (rocketLaunches.size() > 0) { adapter.clear(); adapter.addItems(rocketLaunches); } final DataSaver dataSaver = new DataSaver(context); swipeRefreshLayout.setRefreshing(true); - DataClient.getInstance().getVehicles(name, new Callback() { + DataClient.getInstance().getVehicles(agency, new Callback() { @Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java index 3b265104f..cfe4ebe7e 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java @@ -7,7 +7,6 @@ import android.content.SharedPreferences; import android.os.Build; import android.preference.PreferenceManager; -import android.support.design.widget.FloatingActionButton; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; @@ -17,14 +16,13 @@ import android.widget.TextView; import java.util.Calendar; -import java.util.List; import io.realm.Realm; import io.realm.RealmList; import io.realm.RealmResults; import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.RocketDetail; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.ui.imageviewer.FullscreenImageActivity; import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.Utils; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java index ff518e269..033f376fa 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java @@ -24,7 +24,7 @@ import io.realm.RealmList; import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.utils.Utils; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java index 5eb66154e..54769be3c 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java @@ -54,7 +54,7 @@ import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.services.LibraryDataManager; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.main.MainActivity; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.views.SnackbarHandler; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/UpcomingLaunchesFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/UpcomingLaunchesFragment.java index 040c1e914..1642d7f1d 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/UpcomingLaunchesFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/UpcomingLaunchesFragment.java @@ -51,7 +51,7 @@ import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.util.QueryBuilder; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.main.MainActivity; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.views.SnackbarHandler; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java index fd78f0ce3..625724975 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java @@ -22,7 +22,7 @@ import io.realm.RealmList; import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.Mission; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Mission; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.ui.main.MainActivity; import me.calebjones.spacelaunchnow.utils.Utils; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionFragment.java index 55e0d1471..9640cbaa4 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionFragment.java @@ -34,7 +34,7 @@ import me.calebjones.spacelaunchnow.content.data.DataClientManager; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Mission; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Mission; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.views.SnackbarHandler; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java index 4392476d9..4dd4bdd83 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java @@ -8,7 +8,6 @@ import android.graphics.Typeface; import android.net.Uri; import android.preference.PreferenceManager; -import android.support.design.widget.FloatingActionButton; import android.support.v4.app.ShareCompat; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; @@ -24,7 +23,6 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.simplelist.MaterialSimpleListItem; -import com.bumptech.glide.Glide; import com.crashlytics.android.Crashlytics; import com.mypopsy.maps.StaticMap; @@ -38,7 +36,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.util.DialogAdapter; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.models.realm.RealmStr; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.utils.GlideApp; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardSmallAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardSmallAdapter.java index 5432775b2..281474c83 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardSmallAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardSmallAdapter.java @@ -30,7 +30,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.util.DialogAdapter; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.models.realm.RealmStr; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.utils.Utils; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java index f909a87ed..cce6ce462 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java @@ -26,18 +26,9 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.MotionEvent; import android.view.View; import android.view.ViewAnimationUtils; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.Toast; - -import com.github.amlcurran.showcaseview.OnShowcaseEventListener; -import com.github.amlcurran.showcaseview.ShowcaseView; -import com.github.amlcurran.showcaseview.targets.ViewTarget; - -import org.greenrobot.eventbus.EventBus; import java.util.Calendar; import java.util.Date; @@ -56,13 +47,11 @@ import me.calebjones.spacelaunchnow.common.BaseFragment; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; -import me.calebjones.spacelaunchnow.content.events.FilterViewEvent; import me.calebjones.spacelaunchnow.content.services.LibraryDataManager; import me.calebjones.spacelaunchnow.content.util.QueryBuilder; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.debug.DebugActivity; -import me.calebjones.spacelaunchnow.ui.intro.OnboardingActivity; import me.calebjones.spacelaunchnow.ui.main.MainActivity; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.views.SnackbarHandler; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/LauncherFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/LauncherFragment.java index b2f85cbcc..74faf6263 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/LauncherFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/LauncherFragment.java @@ -21,7 +21,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.common.CustomFragment; -import me.calebjones.spacelaunchnow.data.models.Launcher; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launcher; import me.calebjones.spacelaunchnow.data.networking.error.ErrorUtil; import me.calebjones.spacelaunchnow.data.networking.interfaces.SpaceLaunchNowService; import me.calebjones.spacelaunchnow.data.networking.responses.base.LauncherResponse; @@ -113,7 +113,7 @@ private void loadJSON() { showLoading(); SpaceLaunchNowService request = getSpaceLaunchNowRetrofit().create(SpaceLaunchNowService.class); - Call call = request.getLaunchers(); + Call call = request.getAgencies(); call.enqueue(new Callback() { @Override diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java index 937e1ce8e..373a2558b 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java @@ -8,19 +8,15 @@ import android.widget.ImageView; import android.widget.TextView; -import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; -import com.github.florent37.glidepalette.BitmapPalette; import com.github.florent37.glidepalette.GlidePalette; -import org.w3c.dom.Text; - import java.util.ArrayList; import java.util.List; import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.Launcher; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launcher; import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.OnItemClickListener; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterAdapter.java index a888b81d7..6ffd48ca2 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterAdapter.java @@ -9,7 +9,6 @@ import android.widget.TextView; import com.bumptech.glide.request.RequestOptions; -import com.github.florent37.glidepalette.BitmapPalette; import com.github.florent37.glidepalette.GlidePalette; import java.util.ArrayList; @@ -17,7 +16,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.Orbiter; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.Orbiter; import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.OnItemClickListener; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterFragment.java index a7931b950..c215a3ed0 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterFragment.java @@ -25,7 +25,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.common.CustomFragment; -import me.calebjones.spacelaunchnow.data.models.Orbiter; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.Orbiter; import me.calebjones.spacelaunchnow.data.networking.error.ErrorUtil; import me.calebjones.spacelaunchnow.data.networking.interfaces.SpaceLaunchNowService; import me.calebjones.spacelaunchnow.data.networking.responses.base.OrbiterResponse; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/orbiter/OrbiterDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/orbiter/OrbiterDetailActivity.java index fa23d6a38..e1239e3ab 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/orbiter/OrbiterDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/orbiter/OrbiterDetailActivity.java @@ -24,7 +24,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.common.BaseActivity; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.Orbiter; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.Orbiter; import me.calebjones.spacelaunchnow.ui.main.MainActivity; import me.calebjones.spacelaunchnow.ui.settings.SettingsActivity; import me.calebjones.spacelaunchnow.utils.GlideApp; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/NotificationsFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/NotificationsFragment.java index e5f23a344..c32a38d5c 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/NotificationsFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/NotificationsFragment.java @@ -16,7 +16,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.notifications.NotificationBuilder; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java index 981dce1dd..44e4df5a8 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java @@ -41,14 +41,9 @@ import android.widget.RemoteViews; import android.widget.Toast; -import com.bumptech.glide.Glide; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @@ -57,7 +52,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.utils.customtab.CustomTabActivityHelper; import me.calebjones.spacelaunchnow.utils.customtab.WebViewFallback; import timber.log.Timber; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java index 921b025b0..4af575b87 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java @@ -20,7 +20,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.util.QueryBuilder; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/UpdateLaunchCardJob.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/UpdateLaunchCardJob.java index 578db33de..1af985bef 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/UpdateLaunchCardJob.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/UpdateLaunchCardJob.java @@ -1,35 +1,14 @@ package me.calebjones.spacelaunchnow.widget.launchcard; -import android.app.PendingIntent; -import android.appwidget.AppWidgetHost; -import android.appwidget.AppWidgetManager; import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.annotation.NonNull; -import android.widget.RemoteViews; import com.evernote.android.job.Job; import com.evernote.android.job.JobRequest; import com.evernote.android.job.util.support.PersistableBundleCompat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; - -import io.realm.Realm; -import io.realm.RealmResults; -import io.realm.Sort; -import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; -import me.calebjones.spacelaunchnow.content.util.QueryBuilder; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Launch; -import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; -import me.calebjones.spacelaunchnow.utils.Utils; -import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; -import timber.log.Timber; public class UpdateLaunchCardJob extends Job { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java index 1a5be3434..b47171426 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java @@ -8,7 +8,6 @@ import android.graphics.Color; import android.os.Bundle; import android.preference.PreferenceManager; -import android.support.v4.content.ContextCompat; import android.widget.RemoteViews; import java.text.SimpleDateFormat; @@ -21,7 +20,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.util.QueryBuilder; -import me.calebjones.spacelaunchnow.data.models.Launch; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/UpdateWordTimerJob.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/UpdateWordTimerJob.java index ea21b949c..d981ac78b 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/UpdateWordTimerJob.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/UpdateWordTimerJob.java @@ -1,38 +1,14 @@ package me.calebjones.spacelaunchnow.widget.wordtimer; -import android.app.PendingIntent; -import android.appwidget.AppWidgetHost; -import android.appwidget.AppWidgetManager; import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.Color; -import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.annotation.NonNull; -import android.widget.RemoteViews; import com.evernote.android.job.Job; import com.evernote.android.job.JobRequest; import com.evernote.android.job.util.support.PersistableBundleCompat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; - -import io.realm.Realm; -import io.realm.RealmResults; -import io.realm.Sort; -import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; -import me.calebjones.spacelaunchnow.content.util.QueryBuilder; import me.calebjones.spacelaunchnow.data.models.Constants; -import me.calebjones.spacelaunchnow.data.models.Launch; -import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; -import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; -import me.calebjones.spacelaunchnow.utils.Utils; -import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactManager; -import timber.log.Timber; public class UpdateWordTimerJob extends Job { diff --git a/mobile/version.properties b/mobile/version.properties index 87a5b56cf..0d67edf92 100644 --- a/mobile/version.properties +++ b/mobile/version.properties @@ -1,2 +1,2 @@ -#Tue Dec 12 23:54:45 EST 2017 -AI_VERSION_CODE=1016 +#Wed Dec 13 13:36:36 EST 2017 +AI_VERSION_CODE=1017 diff --git a/wear/version.properties b/wear/version.properties index 0f714a6b8..56d2ae274 100644 --- a/wear/version.properties +++ b/wear/version.properties @@ -1,2 +1,2 @@ -#Tue Dec 12 23:54:48 EST 2017 -AI_VERSION_CODE=1016 +#Wed Dec 13 13:36:37 EST 2017 +AI_VERSION_CODE=1017 From 478c6cf929a78ce4a5d91ba92e9b4efaa2df6c47 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Thu, 14 Dec 2017 02:24:09 -0500 Subject: [PATCH 02/41] WIP --- .../spacelaunchnow/data/models/Constants.java | 5 +- .../data/models/realm/Migration.java | 16 ++ .../Launcher.java | 2 +- .../{Agency.java => LauncherAgency.java} | 18 +- .../models/spacelaunchnow/RocketDetail.java | 10 +- .../networking/interfaces/LibraryService.java | 2 +- .../interfaces/SpaceLaunchNowService.java | 2 +- .../responses/base/LauncherResponse.java | 7 +- .../content/util/QueryBuilder.java | 6 +- .../fragments/AgencyDetailFragment.java | 6 +- .../ui/launcher/VehicleDetailAdapter.java | 223 +++++++-------- .../launches/PreviousLaunchesFragment.java | 6 +- .../launches/UpcomingLaunchesFragment.java | 6 +- .../vehicles/launcher/LauncherFragment.java | 9 +- .../vehicles/launcher/VehicleAdapter.java | 13 +- .../layout-large-land/vehicle_list_item.xml | 268 ----------------- .../res/layout-large/vehicle_list_item.xml | 269 ------------------ .../src/main/res/layout/vehicle_list_item.xml | 121 ++++---- 18 files changed, 233 insertions(+), 756 deletions(-) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/{launchlibrary => spacelaunchnow}/Launcher.java (91%) rename data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/{Agency.java => LauncherAgency.java} (80%) delete mode 100644 mobile/src/main/res/layout-large-land/vehicle_list_item.xml delete mode 100644 mobile/src/main/res/layout-large/vehicle_list_item.xml diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java index 98cbc6cb1..729015c16 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java @@ -25,14 +25,15 @@ public final class Constants { public static final String ACTION_UPDATE_LAUNCH_CARD = "UPDATE_LAUNCH_CARD"; public static final String ACTION_UPDATE_WORD_TIMER = "UPDATE_WORD_TIMER"; public static int NOTIF_ID = 568975; - public static int NOTIF_ID_DAY = 568985; - public static int NOTIF_ID_HOUR = 568995; + public static int NOTIF_ID_HOUR = 568995; public static int DB_SCHEMA_VERSION_1_5_5 = 188; + public static int DB_SCHEMA_VERSION_1_5_6 = 189; public static int DB_SCHEMA_VERSION_1_8_0 = 320; public static int DB_SCHEMA_VERSION_1_8_1 = 322; + public static int DB_SCHEMA_VERSION_1_8_2 = 323; public static String FORECAST_IO_BASE_URL = "https://api.forecast.io/"; public static String API_BASE_URL = "https://api.spacelaunchnow.me/"; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java index 215ff029b..5ea604959 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java @@ -104,6 +104,22 @@ public void apply(DynamicRealmObject obj) { oldVersion++; } + if (oldVersion <= Constants.DB_SCHEMA_VERSION_1_8_2) { + RealmObjectSchema details = schema.get("RocketDetail"); + if (details != null){ + details.renameField("manufacturer", "agency"); + } + + RealmObjectSchema launcherAgency = schema.create("LauncherAgency"); + launcherAgency.addField("agency", String.class, FieldAttribute.PRIMARY_KEY) + .addField("launchers", String.class) + .addField("orbiters", String.class) + .addField("description", String.class) + .addField("imageURL", String.class) + .addField("nationURL", String.class); + oldVersion++; + } + Timber.i("Final Schema - Version %s", newVersion); for (RealmObjectSchema objectSchema : schema.getAll()) { Timber.d("Name: %s Fields: %s", objectSchema.getClassName(), objectSchema.getFieldNames()); diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launcher.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Launcher.java similarity index 91% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launcher.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Launcher.java index f708e52d1..fd525c132 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launcher.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Launcher.java @@ -1,4 +1,4 @@ -package me.calebjones.spacelaunchnow.data.models.launchlibrary; +package me.calebjones.spacelaunchnow.data.models.spacelaunchnow; import com.google.gson.annotations.SerializedName; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Agency.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/LauncherAgency.java similarity index 80% rename from data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Agency.java rename to data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/LauncherAgency.java index df2181418..42484a132 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/Agency.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/LauncherAgency.java @@ -2,21 +2,23 @@ import com.google.gson.annotations.SerializedName; import io.realm.RealmObject; +import io.realm.annotations.PrimaryKey; -public class Agency extends RealmObject{ +public class LauncherAgency extends RealmObject{ + @PrimaryKey @SerializedName(value = "agency") - String agency; + public String agency; @SerializedName(value = "launchers") - String launchers; + public String launchers; @SerializedName(value = "orbiters") - String orbiters; + public String orbiters; @SerializedName(value = "description") - String description; - @SerializedName(value = "image_url") - String imageURL; + public String description; + @SerializedName(value = "image_url") + public String imageURL; @SerializedName(value = "nation_url") - String nationURL; + public String nationURL; public String getAgency() { return agency; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java index 43f5e4dc2..19d2f3806 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java @@ -23,7 +23,7 @@ public class RocketDetail extends RealmObject { @SerializedName(value = "s_family") private String sFamily; @SerializedName(value = "agency") - private String manufacturer; + private String agency; @SerializedName(value = "variant") private String variant; @SerializedName(value = "alias") @@ -93,12 +93,12 @@ public void setsFamily(String sFamily) { this.sFamily = sFamily; } - public String getManufacturer() { - return manufacturer; + public String getAgency() { + return agency; } - public void setManufacturer(String manufacturer) { - this.manufacturer = manufacturer; + public void setAgency(String agency) { + this.agency = agency; } public String getVariant() { diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/LibraryService.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/LibraryService.java index 94323658c..8ba447221 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/LibraryService.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/LibraryService.java @@ -75,7 +75,7 @@ Call getNextUpcomingLaunchesMini(@Query("start_date") String sta @GET("mission/{missionID}?mode=verbose") Call getMissionByID(@Path("missionID") int missionID); - //Get Agency Methods + //Get LauncherAgency Methods @Headers({ "User-Agent: SpaceLaunchNow-" + BuildConfig.VERSION_NAME }) diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/SpaceLaunchNowService.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/SpaceLaunchNowService.java index db10fed10..a0d67c9fc 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/SpaceLaunchNowService.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/interfaces/SpaceLaunchNowService.java @@ -22,7 +22,7 @@ public interface SpaceLaunchNowService { "User-Agent: SpaceLaunchNow-" + BuildConfig.VERSION_NAME }) @GET(version + "/agency/") - Call getAgencies(); + Call getVehicleAgencies(); @Headers({"User-Agent: SpaceLaunchNow-" + BuildConfig.VERSION_NAME}) @GET(version + "/launcher_details/") diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/LauncherResponse.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/LauncherResponse.java index 8846b9ed9..da70d02de 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/LauncherResponse.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/networking/responses/base/LauncherResponse.java @@ -2,14 +2,13 @@ import com.google.gson.annotations.SerializedName; -import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launcher; -import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.Agency; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.LauncherAgency; public class LauncherResponse { @SerializedName(value="results") - private Agency[] launchers; + private LauncherAgency[] launchers; - public Agency[] getLaunchers() { + public LauncherAgency[] getLaunchers() { return launchers; } } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java index 88024da5d..3e8dcadc8 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java @@ -167,8 +167,8 @@ private static void verifyUpSwitches(Context context, SwitchPreferences switchPr } if (agencyArray != null && agencyFilter != null && agencyArray.size() != agencyFilter.length) { - Crashlytics.log("Agency Array: " + agencyArray + " Agency Filter " + agencyFilter); - Toast.makeText(context, "UNKNOWN ERROR - Resetting Agency filter.", Toast.LENGTH_SHORT).show(); + Crashlytics.log("LauncherAgency Array: " + agencyArray + " LauncherAgency Filter " + agencyFilter); + Toast.makeText(context, "UNKNOWN ERROR - Resetting LauncherAgency filter.", Toast.LENGTH_SHORT).show(); switchPreferences.resetAllUpFilters(); if (switchPreferences.isUpFiltered()) { switchPreferences.setUpFiltered(false); @@ -271,7 +271,7 @@ private static RealmQuery filterLocation(RealmQuery query, Array private static RealmQuery filterAgency(RealmQuery query, ArrayList agencyFilter) { boolean firstGroup = true; for (String key : agencyFilter) { - Timber.v("Agency key: %s", key); + Timber.v("LauncherAgency key: %s", key); if (key.contains("NASA")) { if (!firstGroup) { query.or(); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java index 8182a2569..963e86a37 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java @@ -101,7 +101,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa View view; this.sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); this.context = getContext(); - setScreenName("Agency Detail Fragment"); + setScreenName("LauncherAgency Detail Fragment"); sharedPreference = ListPreferences.getInstance(this.context); @@ -185,7 +185,7 @@ private void setNoMissionAgencies() { mission_one.setVisibility(View.GONE); mission_two.setVisibility(View.GONE); - mission_agency_title.setText("Mission Agency"); + mission_agency_title.setText("Mission LauncherAgency"); } private void setOneMissionAgencies() { @@ -378,7 +378,7 @@ private void setNoVehicleAgencies() { launch_one.setVisibility(View.GONE); launch_two.setVisibility(View.GONE); - vehicle_agency_title.setText("Vehicle Agency"); + vehicle_agency_title.setText("Vehicle LauncherAgency"); launch_agency_type.setText("Unknown"); } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java index cfe4ebe7e..1f35d8716 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java @@ -4,10 +4,11 @@ import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Build; -import android.preference.PreferenceManager; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; +import android.support.v7.graphics.Palette; +import android.support.v7.widget.AppCompatButton; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -15,9 +16,10 @@ import android.widget.ImageView; import android.widget.TextView; -import java.util.Calendar; +import com.bumptech.glide.request.RequestOptions; +import com.github.florent37.glidepalette.BitmapPalette; +import com.github.florent37.glidepalette.GlidePalette; -import io.realm.Realm; import io.realm.RealmList; import io.realm.RealmResults; import me.calebjones.spacelaunchnow.R; @@ -32,24 +34,22 @@ public class VehicleDetailAdapter extends RecyclerView.Adapter items; - private static ListPreferences sharedPreference; - private RocketDetail launchVehicle; - private int defaultBackgroundcolor; - private static final int SCALE_DELAY = 30; - private int lastPosition = -1; + private RequestOptions requestOptions; + private int palette; + private Palette.Swatch backgroundColor; - private Realm realm; - - public VehicleDetailAdapter(Context context, Activity activity, Realm realm) { - rightNow = Calendar.getInstance(); - sharedPreference = ListPreferences.getInstance(context); + public VehicleDetailAdapter(Context context, Activity activity) { items = new RealmList<>(); - this.realm = realm; - this.sharedPref = PreferenceManager.getDefaultSharedPreferences(context); - this.mContext = context; + requestOptions = new RequestOptions() + .placeholder(R.drawable.placeholder) + .centerCrop(); + if (ListPreferences.getInstance(mContext).isNightModeActive(mContext)) { + palette = GlidePalette.Profile.MUTED_DARK; + } else { + palette = GlidePalette.Profile.VIBRANT_LIGHT; + } + mContext = context; this.activity = activity; } @@ -71,103 +71,73 @@ public void clear() { @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { - int m_theme; - - this.sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext); - sharedPreference = ListPreferences.getInstance(mContext); - - if (sharedPreference.isNightModeActive(mContext)) { - defaultBackgroundcolor = ContextCompat.getColor(mContext, R.color.colorAccent); - } else { - defaultBackgroundcolor = ContextCompat.getColor(mContext, R.color.darkAccent); - } - View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.vehicle_list_item, viewGroup, false); return new ViewHolder(v); } @Override public void onBindViewHolder(final ViewHolder holder, int i) { - launchVehicle = items.get(holder.getAdapterPosition()); + RocketDetail launchVehicle = items.get(holder.getAdapterPosition()); if (launchVehicle != null) { - holder.vehicle_spec_view.setVisibility(View.VISIBLE); + holder.vehicleSpecView.setVisibility(View.VISIBLE); if (launchVehicle.getDescription() != null && launchVehicle.getDescription().length() > 0) { - holder.launch_vehicle_description.setVisibility(View.VISIBLE); - holder.launch_vehicle_description.setText(launchVehicle.getDescription()); + holder.vehicleDescription.setVisibility(View.VISIBLE); + holder.vehicleDescription.setText(launchVehicle.getDescription()); } else { - holder.launch_vehicle_description.setVisibility(View.GONE); + holder.vehicleDescription.setVisibility(View.GONE); } - holder.launch_vehicle_specs_height.setText(String.format("Height: %s Meters", launchVehicle.getLength())); - holder.launch_vehicle_specs_diameter.setText(String.format("Diameter: %s Meters", launchVehicle.getDiameter())); - holder.launch_vehicle_specs_stages.setText(String.format("Max Stages: %d", launchVehicle.getMaxStage())); - holder.launch_vehicle_specs_leo.setText(String.format("Payload to LEO: %s kg", launchVehicle.getLEOCapacity())); - holder.launch_vehicle_specs_gto.setText(String.format("Payload to GTO: %s kg", launchVehicle.getGTOCapacity())); - holder.launch_vehicle_specs_launch_mass.setText(String.format("Mass at Launch: %s Tons", launchVehicle.getLaunchMass())); - holder.launch_vehicle_specs_thrust.setText(String.format("Thrust at Launch: %s kN", launchVehicle.getTOThrust())); - } else { - holder.launch_vehicle_description.setVisibility(View.GONE); - holder.vehicle_spec_view.setVisibility(View.GONE); - } + holder.vehicleSpecsHeight.setText(String.format("Height: %s Meters", launchVehicle.getLength())); + holder.vehicleSpecsDiameter.setText(String.format("Diameter: %s Meters", launchVehicle.getDiameter())); + holder.vehicleSpecsStages.setText(String.format("Max Stages: %d", launchVehicle.getMaxStage())); + holder.vehicleSpecsLeo.setText(String.format("Payload to LEO: %s kg", launchVehicle.getLEOCapacity())); + holder.vehicleSpecsGto.setText(String.format("Payload to GTO: %s kg", launchVehicle.getGTOCapacity())); + holder.vehicleSpecsLaunchMass.setText(String.format("Mass at Launch: %s Tons", launchVehicle.getLaunchMass())); + holder.vehicleSpecsThrust.setText(String.format("Thrust at Launch: %s kN", launchVehicle.getTOThrust())); - GlideApp.with(mContext) - .load(launchVehicle.getImageURL()) - .placeholder(R.drawable.placeholder) - .error(R.drawable.placeholder) - .into(holder.item_icon); - holder.item_title.setText(launchVehicle.getName() + " " + launchVehicle.getVariant()); + if (backgroundColor != null) { + holder.titleContainer.setBackgroundColor(backgroundColor.getRgb()); + } + if (launchVehicle.getImageURL() != null && launchVehicle.getImageURL().length() > 0) { + holder.vehicleImage.setVisibility(View.VISIBLE); + GlideApp.with(mContext) + .load(launchVehicle.getImageURL()) + .apply(requestOptions) + .into(holder.vehicleImage); + } else { - if (launchVehicle != null) { - if (launchVehicle.getInfoURL() != null && launchVehicle.getInfoURL().length() > 0) { - realm.beginTransaction(); - items.get(i).setInfoURL(launchVehicle.getInfoURL()); - realm.commitTransaction(); - holder.infoButton.setVisibility(View.VISIBLE); - } else if (launchVehicle.getInfoURL() != null && !launchVehicle.getInfoURL().contains("null")) { - if (launchVehicle.getInfoURL().length() > 0) { - holder.infoButton.setVisibility(View.VISIBLE); - } else { - holder.infoButton.setVisibility(View.GONE); - } + holder.vehicleImage.setVisibility(View.GONE); + } + String vehicleName = launchVehicle.getName(); + if (!launchVehicle.getVariant().equals("-")) { + vehicleName = vehicleName + " " + launchVehicle.getVariant(); } - } else if (launchVehicle.getInfoURL() != null && !launchVehicle.getInfoURL().contains("null")) { - if (launchVehicle.getInfoURL().length() > 0) { + holder.vehicleName.setText(vehicleName); + holder.vehicleFamily.setText(launchVehicle.getFamily()); + + if (launchVehicle.getInfoURL() != null + && launchVehicle.getInfoURL().length() > 0 + && !launchVehicle.getInfoURL().contains("null")) { holder.infoButton.setVisibility(View.VISIBLE); } else { holder.infoButton.setVisibility(View.GONE); } - } else { - holder.infoButton.setVisibility(View.GONE); - } - if (launchVehicle != null) { - if (launchVehicle.getWikiURL() != null && launchVehicle.getWikiURL().length() > 0) { - realm.beginTransaction(); - items.get(i).setWikiURL(launchVehicle.getWikiURL()); - realm.commitTransaction(); - holder.wikiButton.setVisibility(View.VISIBLE); - } else if (launchVehicle.getWikiURL() != null && !launchVehicle.getWikiURL().contains("null")) { - if (launchVehicle.getWikiURL().length() > 0) { - holder.wikiButton.setVisibility(View.VISIBLE); - } else { - holder.wikiButton.setVisibility(View.GONE); - } - } - } else if (launchVehicle.getWikiURL() != null && !launchVehicle.getWikiURL().contains("null")) { - if (launchVehicle.getWikiURL().length() > 0) { + + if (launchVehicle.getWikiURL() != null + && launchVehicle.getWikiURL().length() > 0 + && !launchVehicle.getWikiURL().contains("null")) { holder.wikiButton.setVisibility(View.VISIBLE); } else { holder.wikiButton.setVisibility(View.GONE); } - } else { - holder.infoButton.setVisibility(View.GONE); - } - if (holder.infoButton.getVisibility() == View.GONE && holder.wikiButton.getVisibility() == View.GONE) { - holder.button_layout.setVisibility(View.GONE); - } else { - holder.button_layout.setVisibility(View.VISIBLE); + if (holder.infoButton.getVisibility() == View.GONE && holder.wikiButton.getVisibility() == View.GONE) { + holder.button_layout.setVisibility(View.GONE); + } else { + holder.button_layout.setVisibility(View.VISIBLE); + } } } @@ -177,45 +147,58 @@ public int getItemCount() { return items.size(); } + public void updateColor(Palette palette) { + + if (ListPreferences.getInstance(mContext).isNightModeActive(mContext)) { + backgroundColor = palette.getDarkMutedSwatch(); + } else { + backgroundColor = palette.getVibrantSwatch(); + } + } + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - public ImageView item_icon; - public View vehicle_spec_view, vehicle_container, button_layout; - public TextView item_title; - public TextView launch_vehicle_specs_height; - public TextView launch_vehicle_specs_diameter; - public TextView launch_vehicle_specs_stages; - public TextView launch_vehicle_specs_leo; - public TextView launch_vehicle_specs_gto; - public TextView launch_vehicle_specs_launch_mass; - public TextView launch_vehicle_specs_thrust; - public TextView infoButton; - public TextView wikiButton; - public TextView launch_vehicle_description; + public ImageView vehicleImage; + public View vehicleSpecView, vehicleContainer, button_layout; + public TextView vehicleName; + public TextView vehicleFamily; + public TextView vehicleSpecsHeight; + public TextView vehicleSpecsDiameter; + public TextView vehicleSpecsStages; + public TextView vehicleSpecsLeo; + public TextView vehicleSpecsGto; + public TextView vehicleSpecsLaunchMass; + public TextView vehicleSpecsThrust; + public View titleContainer; + public AppCompatButton infoButton; + public AppCompatButton wikiButton; + public TextView vehicleDescription; //Add content to the card public ViewHolder(View view) { super(view); view.setOnClickListener(this); - vehicle_container = view.findViewById(R.id.vehicle_container); - vehicle_spec_view = view.findViewById(R.id.vehicle_spec_view); + vehicleContainer = view.findViewById(R.id.vehicle_container); + vehicleSpecView = view.findViewById(R.id.vehicle_spec_view); + vehicleImage = view.findViewById(R.id.item_icon); + vehicleName = view.findViewById(R.id.item_title); + vehicleFamily = view.findViewById(R.id.text_subtitle); + vehicleSpecsStages = view.findViewById(R.id.launch_vehicle_specs_stages); + vehicleSpecsHeight = view.findViewById(R.id.launch_vehicle_specs_height); + vehicleSpecsDiameter = view.findViewById(R.id.launch_vehicle_specs_diameter); + vehicleSpecsLeo = view.findViewById(R.id.launch_vehicle_specs_leo); + vehicleSpecsGto = view.findViewById(R.id.launch_vehicle_specs_gto); + vehicleSpecsLaunchMass = view.findViewById(R.id.launch_vehicle_specs_launch_mass); + vehicleSpecsThrust = view.findViewById(R.id.launch_vehicle_specs_thrust); + vehicleDescription = view.findViewById(R.id.launch_vehicle_description); button_layout = view.findViewById(R.id.button_layout); - item_icon = (ImageView) view.findViewById(R.id.item_icon); - item_title = (TextView) view.findViewById(R.id.item_title); - launch_vehicle_specs_stages = (TextView) view.findViewById(R.id.launch_vehicle_specs_stages); - launch_vehicle_specs_height = (TextView) view.findViewById(R.id.launch_vehicle_specs_height); - launch_vehicle_specs_diameter = (TextView) view.findViewById(R.id.launch_vehicle_specs_diameter); - launch_vehicle_specs_leo = (TextView) view.findViewById(R.id.launch_vehicle_specs_leo); - launch_vehicle_specs_gto = (TextView) view.findViewById(R.id.launch_vehicle_specs_gto); - launch_vehicle_specs_launch_mass = (TextView) view.findViewById(R.id.launch_vehicle_specs_launch_mass); - launch_vehicle_specs_thrust = (TextView) view.findViewById(R.id.launch_vehicle_specs_thrust); - launch_vehicle_description = (TextView) view.findViewById(R.id.launch_vehicle_description); - infoButton = (TextView) view.findViewById(R.id.infoButton); - wikiButton = (TextView) view.findViewById(R.id.wikiButton); + titleContainer = view.findViewById(R.id.text_container); + infoButton = view.findViewById(R.id.infoButton); + wikiButton = view.findViewById(R.id.wikiButton); infoButton.setOnClickListener(this); wikiButton.setOnClickListener(this); - item_icon.setOnClickListener(this); + vehicleImage.setOnClickListener(this); } //React to click events. @@ -233,7 +216,7 @@ public void onClick(View v) { Intent animateIntent = new Intent(activity, FullscreenImageActivity.class); animateIntent.putExtra("imageURL", items.get(position).getImageURL()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - activity.startActivity(animateIntent, ActivityOptions.makeSceneTransitionAnimation(activity, item_icon, "imageCover").toBundle()); + activity.startActivity(animateIntent, ActivityOptions.makeSceneTransitionAnimation(activity, vehicleImage, "imageCover").toBundle()); } else { activity.startActivity(animateIntent); } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java index 54769be3c..d492c7667 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java @@ -281,9 +281,9 @@ public boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[ } private void showAgencyDialog() { - Analytics.from(getActivity()).sendButtonClicked("Previous Filter - Agency"); + Analytics.from(getActivity()).sendButtonClicked("Previous Filter - LauncherAgency"); new MaterialDialog.Builder(getContext()) - .title("Select an Agency") + .title("Select an LauncherAgency") .content("Check an agency below, to remove all filters use reset icon in the toolbar.") .items(R.array.agencies) .buttonRippleColorRes(R.color.colorAccentLight) @@ -295,7 +295,7 @@ public boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[ for (int i = 0; i < which.length; i++) { keyArray.add(text[i].toString()); } - Analytics.from(getActivity()).sendButtonClicked("Previous Filter - Agency Selection", keyArray.toString()); + Analytics.from(getActivity()).sendButtonClicked("Previous Filter - LauncherAgency Selection", keyArray.toString()); if (keyArray.size() > 0) { switchPreferences.setPrevAgencyFilterArray(keyArray); switchPreferences.setPrevFiltered(true); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/UpcomingLaunchesFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/UpcomingLaunchesFragment.java index 1642d7f1d..f84da29ed 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/UpcomingLaunchesFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/UpcomingLaunchesFragment.java @@ -273,9 +273,9 @@ public boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[ } private void showAgencyDialog() { - Analytics.from(getActivity()).sendButtonClicked("Upcoming Filter - Agency"); + Analytics.from(getActivity()).sendButtonClicked("Upcoming Filter - LauncherAgency"); new MaterialDialog.Builder(getContext()) - .title("Select an Agency") + .title("Select an LauncherAgency") .content("Check an agency below, to remove all filters use reset icon in the toolbar.") .items(R.array.agencies) .buttonRippleColorRes(R.color.colorAccentLight) @@ -287,7 +287,7 @@ public boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[ for (int i = 0; i < which.length; i++) { keyArray.add(text[i].toString()); } - Analytics.from(getActivity()).sendButtonClicked("Upcoming Filter - Agency Selection", keyArray.toString()); + Analytics.from(getActivity()).sendButtonClicked("Upcoming Filter - LauncherAgency Selection", keyArray.toString()); if (keyArray.size() > 0) { switchPreferences.setUpAgencyFilterArray(keyArray); switchPreferences.setUpFiltered(true); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/LauncherFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/LauncherFragment.java index 74faf6263..dd3ee5b5f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/LauncherFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/LauncherFragment.java @@ -21,7 +21,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.common.CustomFragment; -import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launcher; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.LauncherAgency; import me.calebjones.spacelaunchnow.data.networking.error.ErrorUtil; import me.calebjones.spacelaunchnow.data.networking.interfaces.SpaceLaunchNowService; import me.calebjones.spacelaunchnow.data.networking.responses.base.LauncherResponse; @@ -38,7 +38,7 @@ public class LauncherFragment extends CustomFragment implements SwipeRefreshLayo private VehicleAdapter adapter; private RecyclerView.LayoutManager layoutManager; - private List items = new ArrayList<>(); + private List items = new ArrayList<>(); private Context context; private View view; private RecyclerView mRecyclerView; @@ -113,7 +113,7 @@ private void loadJSON() { showLoading(); SpaceLaunchNowService request = getSpaceLaunchNowRetrofit().create(SpaceLaunchNowService.class); - Call call = request.getAgencies(); + Call call = request.getVehicleAgencies(); call.enqueue(new Callback() { @Override @@ -159,12 +159,11 @@ private void showLoading() { @Override public void onClick(View v, int position) { - Analytics.from(context).sendButtonClicked("Launcher clicked", items.get(position).getName()); + Analytics.from(context).sendButtonClicked("Launcher clicked", items.get(position).getAgency()); Gson gson = new Gson(); String jsonItem = gson.toJson(items.get(position)); Intent intent = new Intent(getActivity(), LauncherDetailActivity.class); - intent.putExtra("family", items.get(position).getName()); intent.putExtra("agency", items.get(position).getAgency()); intent.putExtra("json", jsonItem); startActivity(intent); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java index 373a2558b..26bd6ac11 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java @@ -16,7 +16,8 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launcher; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.Launcher; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.LauncherAgency; import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.OnItemClickListener; import timber.log.Timber; @@ -28,7 +29,7 @@ public class VehicleAdapter extends RecyclerView.Adapter launchers = new ArrayList<>(); + private List launchers = new ArrayList<>(); private OnItemClickListener onItemClickListener; private int palette; private RequestOptions requestOptions; @@ -48,7 +49,7 @@ public VehicleAdapter(Context context) { .centerCrop(); } - public void addItems(List items) { + public void addItems(List items) { if (this.launchers == null) { this.launchers = items; } else if (this.launchers.size() == 0) { @@ -73,8 +74,8 @@ public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { @Override public void onBindViewHolder(final ViewHolder holder, int i) { - Launcher launcher = launchers.get(i); - Timber.v("onBindViewHolder %s", launcher.getName()); + LauncherAgency launcher = launchers.get(i); + Timber.v("onBindViewHolder %s", launcher.getAgency()); GlideApp.with(mContext) .load(launcher.getImageURL()) @@ -84,7 +85,7 @@ public void onBindViewHolder(final ViewHolder holder, int i) { .intoBackground(holder.textContainer, GlidePalette.Swatch.RGB) .crossfade(true)) .into(holder.picture); - holder.subTitle.setText(launcher.getName()); + holder.subTitle.setText(launcher.getLaunchers()); holder.name.setText(launcher.getAgency()); } diff --git a/mobile/src/main/res/layout-large-land/vehicle_list_item.xml b/mobile/src/main/res/layout-large-land/vehicle_list_item.xml deleted file mode 100644 index c36adb6e6..000000000 --- a/mobile/src/main/res/layout-large-land/vehicle_list_item.xml +++ /dev/null @@ -1,268 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mobile/src/main/res/layout-large/vehicle_list_item.xml b/mobile/src/main/res/layout-large/vehicle_list_item.xml deleted file mode 100644 index 7e06a42e2..000000000 --- a/mobile/src/main/res/layout-large/vehicle_list_item.xml +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mobile/src/main/res/layout/vehicle_list_item.xml b/mobile/src/main/res/layout/vehicle_list_item.xml index ac7f5de9d..fce63acaf 100644 --- a/mobile/src/main/res/layout/vehicle_list_item.xml +++ b/mobile/src/main/res/layout/vehicle_list_item.xml @@ -1,14 +1,14 @@ + android:transitionGroup="true"> - - + - - + android:orientation="vertical" + android:padding="6dp"> + + + + + + + @@ -76,15 +89,15 @@ android:id="@+id/vehicle_spec_view" android:layout_width="match_parent" android:layout_height="match_parent" + android:layout_marginBottom="8dp" android:layout_marginLeft="12dp" android:layout_marginRight="12dp" android:layout_marginTop="8dp" - android:layout_marginBottom="8dp" android:orientation="vertical"> + android:gravity="bottom" + android:orientation="horizontal"> + android:textSize="12sp" /> + android:textSize="12sp" /> From c309afe3aac694e5ead8321cea97e412a06b6c5e Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Thu, 14 Dec 2017 02:24:17 -0500 Subject: [PATCH 03/41] This too --- .../ui/launcher/LauncherDetailActivity.java | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java index 3fee01b8b..4cd55d57f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java @@ -6,10 +6,13 @@ import android.graphics.Color; import android.os.Build; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.design.widget.AppBarLayout; +import android.support.design.widget.CollapsingToolbarLayout; import android.support.design.widget.CoordinatorLayout; import android.support.v4.content.ContextCompat; import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.graphics.Palette; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; @@ -23,6 +26,8 @@ import android.widget.TextView; import android.widget.Toast; +import com.github.florent37.glidepalette.BitmapPalette; +import com.github.florent37.glidepalette.GlidePalette; import com.google.gson.Gson; import de.hdodenhof.circleimageview.CircleImageView; @@ -32,7 +37,8 @@ import me.calebjones.spacelaunchnow.common.BaseActivity; import me.calebjones.spacelaunchnow.content.data.DataSaver; import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launcher; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.Launcher; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.LauncherAgency; import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.data.networking.DataClient; import me.calebjones.spacelaunchnow.data.networking.responses.base.VehicleResponse; @@ -63,6 +69,7 @@ public class LauncherDetailActivity extends BaseActivity implements AppBarLayout private AppBarLayout appBarLayout; private SwipeRefreshLayout swipeRefreshLayout; private CoordinatorLayout coordinator; + private CollapsingToolbarLayout collapsingToolbar; private int mMaxScrollSize; public LauncherDetailActivity() { @@ -96,6 +103,7 @@ protected void onCreate(Bundle savedInstanceState) { detail_vehicle_agency = (TextView) findViewById(R.id.detail_title); detail_profile_image = (CircleImageView) findViewById(R.id.detail_profile_image); detail_profile_backdrop = (ImageView) findViewById(R.id.detail_profile_backdrop); + collapsingToolbar = findViewById(R.id.main_collapsing_bar); appBarLayout = (AppBarLayout) findViewById(R.id.detail_appbar); swipeRefreshLayout = findViewById(R.id.vehicle_swipe_refresh); coordinator = findViewById(R.id.coordinator_layout); @@ -153,7 +161,7 @@ public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { getSupportActionBar().setDisplayShowTitleEnabled(false); } } - adapter = new VehicleDetailAdapter(context, this, getRealm()); + adapter = new VehicleDetailAdapter(context, this); mRecyclerView = (RecyclerView) findViewById(R.id.vehicle_detail_list); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); mRecyclerView.setLayoutManager(linearLayoutManager); @@ -168,7 +176,7 @@ public int reverseNumber(int num, int min, int max) { public void displayRockets() { Intent intent = getIntent(); Gson gson = new Gson(); - final Launcher launcher = gson.fromJson(intent.getStringExtra("json"), Launcher.class); + final LauncherAgency launcher = gson.fromJson(intent.getStringExtra("json"), LauncherAgency.class); if (launcher == null) { Toast.makeText(context, "Error - Unable to load launcher details.", Toast.LENGTH_SHORT).show(); @@ -177,18 +185,25 @@ public void displayRockets() { startActivity(homeIntent); } - final String name = launcher.getName(); - String agency = launcher.getAgency(); + String name = "Unknown"; + if (launcher != null) { + name = launcher.getLaunchers(); + } + String agency = "Unknown"; + if (launcher != null) { + agency = launcher.getAgency(); + } detail_rocket.setText(name); detail_vehicle_agency.setText(agency); - rocketLaunches = getRealm().where(RocketDetail.class).contains("manufacturer", agency).findAll(); + rocketLaunches = getRealm().where(RocketDetail.class).contains("agency", agency).findAll(); if (rocketLaunches.size() > 0) { adapter.clear(); adapter.addItems(rocketLaunches); } final DataSaver dataSaver = new DataSaver(context); swipeRefreshLayout.setRefreshing(true); + final String finalAgency = agency; DataClient.getInstance().getVehicles(agency, new Callback() { @Override public void onResponse(Call call, Response response) { @@ -198,11 +213,11 @@ public void onResponse(Call call, Response res getRealm().executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { - getRealm().where(RocketDetail.class).contains("family",name).findAll().deleteAllFromRealm(); + getRealm().where(RocketDetail.class).contains("agency", finalAgency).findAll().deleteAllFromRealm(); } }); dataSaver.saveObjectsToRealm(details); - rocketLaunches = getRealm().where(RocketDetail.class).contains("family", name).findAll(); + rocketLaunches = getRealm().where(RocketDetail.class).contains("agency", finalAgency).findAll(); adapter.clear(); adapter.addItems(rocketLaunches); } else { @@ -228,11 +243,37 @@ public void onFailure(Call call, Throwable t) { private void applyProfileBackdrop(String drawableURL) { Timber.d("LauncherDetailActivity - Loading Backdrop Image url: %s ", drawableURL); + int palette; + if (ListPreferences.getInstance(context).isNightModeActive(context)) { + palette = GlidePalette.Profile.MUTED_DARK; + } else { + palette = GlidePalette.Profile.VIBRANT; + } GlideApp.with(this) .load(drawableURL) .centerCrop() - .placeholder(R.drawable.icon_international) + .listener(GlidePalette.with(drawableURL) + .use(palette) + .intoCallBack(new BitmapPalette.CallBack() { + @Override + public void onPaletteLoaded(@Nullable Palette palette) { + if (ListPreferences.getInstance(context).isNightModeActive(context)) { + if (palette != null) { + appBarLayout.setBackgroundColor(palette.getDarkMutedSwatch().getRgb()); + } + } else { + if (palette != null) { + appBarLayout.setBackgroundColor(palette.getVibrantSwatch().getRgb()); + } + } + + adapter.updateColor(palette); + adapter.notifyDataSetChanged(); + } + }) + .crossfade(true)) .into(detail_profile_backdrop); + } private void applyProfileLogo(String url) { From 7c4d580d55490feefb54af35e1bd3fedc5c3aece Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Fri, 15 Dec 2017 14:07:33 -0500 Subject: [PATCH 04/41] Fix Launchers and Orbiters --- mobile/src/main/AndroidManifest.xml | 2 +- .../activity/LaunchDetailActivity.java | 27 --- .../ui/launcher/LauncherDetailActivity.java | 111 ++++------ .../ui/launcher/VehicleDetailAdapter.java | 23 +- .../vehicles/launcher/VehicleAdapter.java | 34 ++- .../main/vehicles/orbiter/OrbiterAdapter.java | 35 ++- .../ui/orbiter/OrbiterDetailActivity.java | 64 +++++- .../views/CustomOnOffsetChangedListener.java | 4 + .../res/layout/activity_launch_detail.xml | 2 - .../res/layout/activity_orbiter_detail.xml | 21 +- .../main/res/layout/activity_vehicle_list.xml | 203 +++++++++--------- 11 files changed, 286 insertions(+), 240 deletions(-) diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml index 10f30e5c3..39d7a8334 100644 --- a/mobile/src/main/AndroidManifest.xml +++ b/mobile/src/main/AndroidManifest.xml @@ -76,7 +76,7 @@ android:parentActivityName=".ui.main.MainActivity" android:theme="@style/CustomPreferenceTheme" /> - + diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java index b41329ba4..9a8b7efb2 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java @@ -298,11 +298,6 @@ protected void onDestroy() { super.onDestroy(); } - public int reverseNumber(int num, int min, int max) { - int number = (max + min) - num; - return number; - } - private void findProfileLogo() { //Default location, mission is unknown. @@ -424,13 +419,6 @@ public Launch getLaunch() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { - int totalScroll = appBarLayout.getTotalScrollRange(); - int currentScroll = totalScroll + verticalOffset; - - int color = statusColor; - int r = (color >> 16) & 0xFF; - int g = (color >> 8) & 0xFF; - int b = (color >> 0) & 0xFF; if (mMaxScrollSize == 0) { mMaxScrollSize = appBarLayout.getTotalScrollRange(); @@ -456,21 +444,6 @@ public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { fabShare.show(); } - -// if ((currentScroll) < 100) { -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { -// -// Window window = getWindow(); -// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); -// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); -// window.setStatusBarColor(Color.argb(reverseNumber(currentScroll, 0, 255), r, g, b)); -// } -// } else { -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { -// Window window = getWindow(); -// window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); -// } -// } } @Override diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java index 4cd55d57f..fd4287b88 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/LauncherDetailActivity.java @@ -46,6 +46,7 @@ import me.calebjones.spacelaunchnow.ui.settings.SettingsActivity; import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.Utils; +import me.calebjones.spacelaunchnow.utils.views.CustomOnOffsetChangedListener; import me.calebjones.spacelaunchnow.utils.views.SnackbarHandler; import retrofit2.Call; import retrofit2.Callback; @@ -56,9 +57,6 @@ public class LauncherDetailActivity extends BaseActivity implements AppBarLayout private static final int PERCENTAGE_TO_ANIMATE_AVATAR = 20; private boolean mIsAvatarShown = true; - - private ListPreferences sharedPreference; - private Context context; private RecyclerView mRecyclerView; private TextView toolbarTitle, detail_rocket, detail_vehicle_agency; @@ -67,10 +65,12 @@ public class LauncherDetailActivity extends BaseActivity implements AppBarLayout private VehicleDetailAdapter adapter; private RealmResults rocketLaunches; private AppBarLayout appBarLayout; - private SwipeRefreshLayout swipeRefreshLayout; - private CoordinatorLayout coordinator; private CollapsingToolbarLayout collapsingToolbar; private int mMaxScrollSize; + private ListPreferences sharedPreference; + private int statusColor; + private CoordinatorLayout coordinatorLayout; + private CustomOnOffsetChangedListener customOnOffsetChangedListener; public LauncherDetailActivity() { super("Launcher Detail Activity"); @@ -78,9 +78,10 @@ public LauncherDetailActivity() { @Override protected void onCreate(Bundle savedInstanceState) { - int m_theme; - final int statusColor; this.context = getApplicationContext(); + setTheme(R.style.BaseAppTheme); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_vehicle_list); sharedPreference = ListPreferences.getInstance(this.context); @@ -90,13 +91,6 @@ protected void onCreate(Bundle savedInstanceState) { statusColor = ContextCompat.getColor(context, R.color.colorPrimaryDark); } - m_theme = R.style.BaseAppTheme; - - setTheme(m_theme); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_vehicle_list); - Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar); toolbarTitle = (TextView) findViewById(R.id.title_text); detail_rocket = (TextView) findViewById(R.id.detail_sub_title); @@ -104,10 +98,8 @@ protected void onCreate(Bundle savedInstanceState) { detail_profile_image = (CircleImageView) findViewById(R.id.detail_profile_image); detail_profile_backdrop = (ImageView) findViewById(R.id.detail_profile_backdrop); collapsingToolbar = findViewById(R.id.main_collapsing_bar); + coordinatorLayout = findViewById(R.id.coordinatorLayout); appBarLayout = (AppBarLayout) findViewById(R.id.detail_appbar); - swipeRefreshLayout = findViewById(R.id.vehicle_swipe_refresh); - coordinator = findViewById(R.id.coordinator_layout); - swipeRefreshLayout.setEnabled(false); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -121,37 +113,11 @@ protected void onCreate(Bundle savedInstanceState) { detail_profile_image.setScaleX(1); detail_profile_image.setScaleY(1); } - + customOnOffsetChangedListener = new CustomOnOffsetChangedListener(statusColor, getWindow()); appBarLayout.addOnOffsetChangedListener(this); + appBarLayout.addOnOffsetChangedListener(customOnOffsetChangedListener); mMaxScrollSize = appBarLayout.getTotalScrollRange(); - appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { - @Override - public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { - int totalScroll = appBarLayout.getTotalScrollRange(); - int currentScroll = totalScroll + verticalOffset; - - int color = statusColor; - int r = (color >> 16) & 0xFF; - int g = (color >> 8) & 0xFF; - int b = (color >> 0) & 0xFF; - - if ((currentScroll) < 255) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - - Window window = getWindow(); - window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); - window.setStatusBarColor(Color.argb(reverseNumber(currentScroll, 0, 255), r, g, b)); - } - } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - Window window = getWindow(); - window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - } - } - } - }); if (toolbar != null) { setSupportActionBar(toolbar); @@ -169,10 +135,6 @@ public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { displayRockets(); } - public int reverseNumber(int num, int min, int max) { - return (max + min) - num; - } - public void displayRockets() { Intent intent = getIntent(); Gson gson = new Gson(); @@ -202,7 +164,7 @@ public void displayRockets() { adapter.addItems(rocketLaunches); } final DataSaver dataSaver = new DataSaver(context); - swipeRefreshLayout.setRefreshing(true); +// swipeRefreshLayout.setRefreshing(true); final String finalAgency = agency; DataClient.getInstance().getVehicles(agency, new Callback() { @Override @@ -221,18 +183,17 @@ public void execute(Realm realm) { adapter.clear(); adapter.addItems(rocketLaunches); } else { - SnackbarHandler.showErrorSnackbar(context, coordinator, "Error no launch vehicles found."); + SnackbarHandler.showErrorSnackbar(context, coordinatorLayout, "Error no launch vehicles found."); } } else { - SnackbarHandler.showErrorSnackbar(context, coordinator, "Error loading launch vehicles."); + SnackbarHandler.showErrorSnackbar(context, coordinatorLayout, "Error loading launch vehicles."); } - swipeRefreshLayout.setRefreshing(false); } @Override public void onFailure(Call call, Throwable t) { - swipeRefreshLayout.setRefreshing(false); - SnackbarHandler.showErrorSnackbar(context, coordinator, String.format("Error: %s", t.getLocalizedMessage())); +// swipeRefreshLayout.setRefreshing(false); + SnackbarHandler.showErrorSnackbar(context, coordinatorLayout, String.format("Error: %s", t.getLocalizedMessage())); } }); @@ -259,16 +220,37 @@ private void applyProfileBackdrop(String drawableURL) { public void onPaletteLoaded(@Nullable Palette palette) { if (ListPreferences.getInstance(context).isNightModeActive(context)) { if (palette != null) { - appBarLayout.setBackgroundColor(palette.getDarkMutedSwatch().getRgb()); + Palette.Swatch color = null; + if (palette.getDarkMutedSwatch() != null) { + color = palette.getDarkMutedSwatch(); + } else if (palette.getDarkVibrantSwatch() != null){ + color = palette.getDarkVibrantSwatch(); + } + if (color != null) { + collapsingToolbar.setContentScrimColor(color.getRgb()); + customOnOffsetChangedListener.updateStatusColor(color.getRgb()); + appBarLayout.setBackgroundColor(color.getRgb()); + adapter.updateColor(color.getRgb()); + adapter.notifyDataSetChanged(); + } } } else { if (palette != null) { - appBarLayout.setBackgroundColor(palette.getVibrantSwatch().getRgb()); + Palette.Swatch color = null; + if (palette.getVibrantSwatch() != null) { + color = palette.getVibrantSwatch(); + } else if (palette.getMutedSwatch() != null){ + color = palette.getMutedSwatch(); + } + if (color != null) { + collapsingToolbar.setContentScrimColor(color.getRgb()); + customOnOffsetChangedListener.updateStatusColor(color.getRgb()); + appBarLayout.setBackgroundColor(color.getRgb()); + adapter.updateColor(color.getRgb()); + adapter.notifyDataSetChanged(); + } } } - - adapter.updateColor(palette); - adapter.notifyDataSetChanged(); } }) .crossfade(true)) @@ -286,19 +268,10 @@ private void applyProfileLogo(String url) { .into(detail_profile_image); } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private void setupWindowAnimations() { - Slide slide = new Slide(); - slide.setDuration(1000); - getWindow().setReturnTransition(slide); - getWindow().setEnterTransition(slide); - } - @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.main_menu, menu); return true; } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java index 1f35d8716..835bb1c09 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launcher/VehicleDetailAdapter.java @@ -36,19 +36,13 @@ public class VehicleDetailAdapter extends RecyclerView.Adapter items; private RequestOptions requestOptions; - private int palette; - private Palette.Swatch backgroundColor; + private int backgroundColor = 0; public VehicleDetailAdapter(Context context, Activity activity) { items = new RealmList<>(); requestOptions = new RequestOptions() .placeholder(R.drawable.placeholder) .centerCrop(); - if (ListPreferences.getInstance(mContext).isNightModeActive(mContext)) { - palette = GlidePalette.Profile.MUTED_DARK; - } else { - palette = GlidePalette.Profile.VIBRANT_LIGHT; - } mContext = context; this.activity = activity; } @@ -96,8 +90,8 @@ public void onBindViewHolder(final ViewHolder holder, int i) { holder.vehicleSpecsThrust.setText(String.format("Thrust at Launch: %s kN", launchVehicle.getTOThrust())); - if (backgroundColor != null) { - holder.titleContainer.setBackgroundColor(backgroundColor.getRgb()); + if (backgroundColor != 0) { + holder.titleContainer.setBackgroundColor(backgroundColor); } if (launchVehicle.getImageURL() != null && launchVehicle.getImageURL().length() > 0) { holder.vehicleImage.setVisibility(View.VISIBLE); @@ -147,13 +141,12 @@ public int getItemCount() { return items.size(); } - public void updateColor(Palette palette) { + public void updateColor(int color) { + + backgroundColor = color; + + backgroundColor = color; - if (ListPreferences.getInstance(mContext).isNightModeActive(mContext)) { - backgroundColor = palette.getDarkMutedSwatch(); - } else { - backgroundColor = palette.getVibrantSwatch(); - } } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java index 26bd6ac11..3d106b03a 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/launcher/VehicleAdapter.java @@ -1,6 +1,8 @@ package me.calebjones.spacelaunchnow.ui.main.vehicles.launcher; import android.content.Context; +import android.support.annotation.Nullable; +import android.support.v7.graphics.Palette; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -9,6 +11,7 @@ import android.widget.TextView; import com.bumptech.glide.request.RequestOptions; +import com.github.florent37.glidepalette.BitmapPalette; import com.github.florent37.glidepalette.GlidePalette; import java.util.ArrayList; @@ -31,14 +34,17 @@ public class VehicleAdapter extends RecyclerView.Adapter launchers = new ArrayList<>(); private OnItemClickListener onItemClickListener; - private int palette; + private boolean night = false; private RequestOptions requestOptions; + private int palette; public VehicleAdapter(Context context) { launchers = new ArrayList(); this.mContext = context; - if (ListPreferences.getInstance(mContext).isNightModeActive(mContext)) { + night = ListPreferences.getInstance(mContext).isNightModeActive(mContext); + + if (ListPreferences.getInstance(context).isNightModeActive(context)) { palette = GlidePalette.Profile.MUTED_DARK; } else { palette = GlidePalette.Profile.VIBRANT; @@ -82,6 +88,30 @@ public void onBindViewHolder(final ViewHolder holder, int i) { .apply(requestOptions) .listener(GlidePalette.with(launcher.getImageURL()) .use(palette) + .intoCallBack(new BitmapPalette.CallBack() { + @Override + public void onPaletteLoaded(@Nullable Palette palette) { + Palette.Swatch color = null; + if (palette != null) { + if (night) { + if (palette.getDarkMutedSwatch() != null) { + color = palette.getDarkMutedSwatch(); + } else if (palette.getDarkVibrantSwatch() != null) { + color = palette.getDarkVibrantSwatch(); + } + } else { + if (palette.getVibrantSwatch() != null) { + color = palette.getVibrantSwatch(); + } else if (palette.getMutedSwatch() != null) { + color = palette.getMutedSwatch(); + } + } + if (color != null) { + holder.textContainer.setBackgroundColor(color.getRgb()); + } + } + } + }) .intoBackground(holder.textContainer, GlidePalette.Swatch.RGB) .crossfade(true)) .into(holder.picture); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterAdapter.java index 6ffd48ca2..3f6ab6e8e 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/vehicles/orbiter/OrbiterAdapter.java @@ -1,6 +1,8 @@ package me.calebjones.spacelaunchnow.ui.main.vehicles.orbiter; import android.content.Context; +import android.support.annotation.Nullable; +import android.support.v7.graphics.Palette; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -9,6 +11,7 @@ import android.widget.TextView; import com.bumptech.glide.request.RequestOptions; +import com.github.florent37.glidepalette.BitmapPalette; import com.github.florent37.glidepalette.GlidePalette; import java.util.ArrayList; @@ -30,14 +33,17 @@ public class OrbiterAdapter extends RecyclerView.Adapter orbiters = new ArrayList(); private OnItemClickListener onItemClickListener; - private int palette; + private boolean night = false; private RequestOptions requestOptions; + private int palette; public OrbiterAdapter(Context context) { orbiters = new ArrayList(); this.mContext = context; - if (ListPreferences.getInstance(mContext).isNightModeActive(mContext)) { + night = ListPreferences.getInstance(mContext).isNightModeActive(mContext); + + if (ListPreferences.getInstance(context).isNightModeActive(context)) { palette = GlidePalette.Profile.MUTED_DARK; } else { palette = GlidePalette.Profile.VIBRANT; @@ -81,7 +87,30 @@ public void onBindViewHolder(final ViewHolder holder, int i) { .apply(requestOptions) .listener(GlidePalette.with(orbiter.getImageURL()) .use(palette) - .intoBackground(holder.textContainer, GlidePalette.Swatch.RGB) + .intoCallBack(new BitmapPalette.CallBack() { + @Override + public void onPaletteLoaded(@Nullable Palette palette) { + Palette.Swatch color = null; + if (palette != null) { + if (night) { + if (palette.getDarkMutedSwatch() != null) { + color = palette.getDarkMutedSwatch(); + } else if (palette.getDarkVibrantSwatch() != null) { + color = palette.getDarkVibrantSwatch(); + } + } else { + if (palette.getVibrantSwatch() != null) { + color = palette.getVibrantSwatch(); + } else if (palette.getMutedSwatch() != null) { + color = palette.getMutedSwatch(); + } + } + if (color != null) { + holder.textContainer.setBackgroundColor(color.getRgb()); + } + } + } + }) .crossfade(true)) .into(holder.picture); holder.name.setText(orbiter.getName()); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/orbiter/OrbiterDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/orbiter/OrbiterDetailActivity.java index e1239e3ab..bd4e0994d 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/orbiter/OrbiterDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/orbiter/OrbiterDetailActivity.java @@ -6,8 +6,12 @@ import android.content.Intent; import android.os.Build; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.design.widget.AppBarLayout; +import android.support.design.widget.CollapsingToolbarLayout; +import android.support.design.widget.CoordinatorLayout; import android.support.v4.content.ContextCompat; +import android.support.v7.graphics.Palette; import android.support.v7.widget.Toolbar; import android.transition.Slide; import android.view.Menu; @@ -18,6 +22,8 @@ import android.widget.TextView; import android.widget.Toast; +import com.github.florent37.glidepalette.BitmapPalette; +import com.github.florent37.glidepalette.GlidePalette; import com.google.gson.Gson; import de.hdodenhof.circleimageview.CircleImageView; @@ -49,7 +55,9 @@ public class OrbiterDetailActivity extends BaseActivity implements AppBarLayout. private ImageView detail_profile_backdrop; private CircleImageView detail_profile_image; private AppBarLayout appBarLayout; + private CollapsingToolbarLayout collapsingToolbarLayout; private int mMaxScrollSize; + private CustomOnOffsetChangedListener customOnOffsetChangedListener; public OrbiterDetailActivity() { super("Orbiter Detail Activity"); @@ -91,6 +99,7 @@ protected void onCreate(Bundle savedInstanceState) { orbiter_history_description = (TextView) findViewById(R.id.orbiter_history_description); orbiter_vehicle_card = findViewById(R.id.orbiter_vehicle_card); title_container = findViewById(R.id.detail_title_container); + collapsingToolbarLayout = findViewById(R.id.collapsing); gridview = findViewById(R.id.vehicle_detail_list); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -106,16 +115,16 @@ protected void onCreate(Bundle savedInstanceState) { // Add a listener to get noticed when the transition ends to animate the view ViewPropertyAnimator showTitleAnimator = Utils.showViewByScale(detail_profile_image); - showTitleAnimator.setStartDelay(750); + showTitleAnimator.setStartDelay(500); } else { detail_profile_image.setScaleX(1); detail_profile_image.setScaleY(1); } - + customOnOffsetChangedListener = new CustomOnOffsetChangedListener(statusColor, getWindow()); appBarLayout.addOnOffsetChangedListener(this); + appBarLayout.addOnOffsetChangedListener(customOnOffsetChangedListener); mMaxScrollSize = appBarLayout.getTotalScrollRange(); - appBarLayout.addOnOffsetChangedListener(new CustomOnOffsetChangedListener(statusColor, getWindow())); if (toolbar != null) { setSupportActionBar(toolbar); @@ -151,6 +160,55 @@ public void displayOrbiterDetails() { .centerCrop() .into(detail_profile_backdrop); + int palette; + if (ListPreferences.getInstance(context).isNightModeActive(context)) { + palette = GlidePalette.Profile.MUTED_DARK; + } else { + palette = GlidePalette.Profile.VIBRANT; + } + + GlideApp.with(this) + .load(orbiter.getImageURL()) + .centerCrop() + .listener(GlidePalette.with(orbiter.getImageURL()) + .use(palette) + .intoCallBack(new BitmapPalette.CallBack() { + @Override + public void onPaletteLoaded(@Nullable Palette palette) { + if (ListPreferences.getInstance(context).isNightModeActive(context)) { + if (palette != null) { + Palette.Swatch color = null; + if (palette.getDarkMutedSwatch() != null) { + color = palette.getDarkMutedSwatch(); + } else if (palette.getDarkVibrantSwatch() != null){ + color = palette.getDarkVibrantSwatch(); + } + if (color != null) { + collapsingToolbarLayout.setContentScrimColor(color.getRgb()); + customOnOffsetChangedListener.updateStatusColor(color.getRgb()); + appBarLayout.setBackgroundColor(color.getRgb()); + } + } + } else { + if (palette != null) { + Palette.Swatch color = null; + if (palette.getVibrantSwatch() != null) { + color = palette.getVibrantSwatch(); + } else if (palette.getMutedSwatch() != null){ + color = palette.getMutedSwatch(); + } + if (color != null) { + collapsingToolbarLayout.setContentScrimColor(color.getRgb()); + customOnOffsetChangedListener.updateStatusColor(color.getRgb()); + appBarLayout.setBackgroundColor(color.getRgb()); + } + } + } + } + }) + .crossfade(true)) + .into(detail_profile_backdrop); + GlideApp.with(this) .load(orbiter.getNationURL()) .centerCrop() diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/views/CustomOnOffsetChangedListener.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/views/CustomOnOffsetChangedListener.java index 5ae7ebb84..e45a6808c 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/views/CustomOnOffsetChangedListener.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/views/CustomOnOffsetChangedListener.java @@ -18,6 +18,10 @@ public CustomOnOffsetChangedListener(int statusColor, Window window) { this.window = window; } + public void updateStatusColor(int statusColor){ + this.statusColor = statusColor; + } + @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { int totalScroll = appBarLayout.getTotalScrollRange(); diff --git a/mobile/src/main/res/layout/activity_launch_detail.xml b/mobile/src/main/res/layout/activity_launch_detail.xml index e6bf852d6..529b07c69 100644 --- a/mobile/src/main/res/layout/activity_launch_detail.xml +++ b/mobile/src/main/res/layout/activity_launch_detail.xml @@ -31,7 +31,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> - ​ - ​ - - ​ - ​ - ​ - ​ + app:layout_scrollFlags="scroll" + app:srcCompat="@drawable/icon_international" /> + android:textColor="@android:color/white" /> ​ + android:textSize="12sp" + android:visibility="visible" /> @@ -197,8 +194,8 @@ android:id="@+id/orbiter_description" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="4dp" android:layout_marginBottom="8dp" + android:layout_marginTop="4dp" android:text="Unknown Orbiter - Description unavailable." /> diff --git a/mobile/src/main/res/layout/activity_vehicle_list.xml b/mobile/src/main/res/layout/activity_vehicle_list.xml index 537fce47c..35a02f57b 100644 --- a/mobile/src/main/res/layout/activity_vehicle_list.xml +++ b/mobile/src/main/res/layout/activity_vehicle_list.xml @@ -1,122 +1,113 @@ + + - + android:layout_height="wrap_content" + android:fitsSystemWindows="true" + android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> + ​ - + android:layout_height="224dp" + android:fitsSystemWindows="true" + app:contentScrim="?attr/colorPrimary" + app:expandedTitleMarginEnd="64dp" + app:expandedTitleMarginStart="48dp" + app:layout_scrollFlags="scroll"> ​ - - ​ - - - ​ - - - - - - ​ - - - - - - ​ - - - ​ - - - ​ - - - ​ - - - - - - - + android:fitsSystemWindows="true" + android:scaleType="centerCrop" + android:transitionName="imageCover" + app:layout_collapseMode="parallax" + app:srcCompat="@drawable/placeholder" /> + + + + ​ + + + + + + ​ + + + ​ + + + ​ + + ​ + + - \ No newline at end of file + + + From a6ed154243944bf54d05add960f14de9abbed1fb Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Sat, 16 Dec 2017 00:29:04 -0500 Subject: [PATCH 05/41] 2.0.0 WIP --- .../fragments/SummaryDetailFragment.java | 4 - .../ui/main/next/CardBigAdapter.java | 33 +- .../ui/main/next/CardSmallAdapter.java | 518 ------------------ .../ui/main/next/NextLaunchFragment.java | 70 +-- .../layout-large-port/content_card_item.xml | 264 --------- .../src/main/res/layout/content_card_item.xml | 137 ++--- .../main/res/layout/detail_launch_summary.xml | 67 ++- .../src/main/res/layout/fragment_upcoming.xml | 4 +- mobile/src/main/res/values/strings.xml | 6 +- .../main/res/xml/appearance_preferences.xml | 6 - 10 files changed, 147 insertions(+), 962 deletions(-) delete mode 100644 mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardSmallAdapter.java delete mode 100644 mobile/src/main/res/layout-large-port/content_card_item.xml diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java index 8b20cd37d..b463b644c 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java @@ -587,22 +587,18 @@ public boolean onPreDraw() { } //GO for launch launch_status.setText(go); - launch_status.setTextColor(ContextCompat.getColor(context, R.color.colorGo)); break; case 2: //NO GO for launch launch_status.setText(R.string.status_nogo); - launch_status.setTextColor(ContextCompat.getColor(context, R.color.colorAccent)); break; case 3: //Success for launch launch_status.setText(R.string.status_success); - launch_status.setTextColor(ContextCompat.getColor(context, R.color.colorGo)); break; case 4: //Failure to launch launch_status.setText(R.string.status_failure); - launch_status.setTextColor(ContextCompat.getColor(context, R.color.colorAccent)); break; } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java index 4dd4bdd83..67c9924c5 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java @@ -133,13 +133,9 @@ public void onBindViewHolder(final ViewHolder holder, int i) { //Retrieve missionType if (launchItem.getMissions().size() != 0) { - Utils.setCategoryIcon(holder.categoryIcon, launchItem.getMissions().get(0).getTypeName(), night); + Utils.setCategoryIcon(holder.categoryIcon, launchItem.getMissions().get(0).getTypeName(), true); } else { - if (night) { - holder.categoryIcon.setImageResource(R.drawable.ic_unknown_white); - } else { - holder.categoryIcon.setImageResource(R.drawable.ic_unknown); - } + holder.categoryIcon.setImageResource(R.drawable.ic_unknown_white); } double dlat = 0; @@ -160,7 +156,7 @@ public void onBindViewHolder(final ViewHolder holder, int i) { final Resources res = context.getResources(); final StaticMap map = new StaticMap() .center(dlat, dlon) - .scale(4) + .scale(1) .type(StaticMap.Type.ROADMAP) .zoom(5) .marker(dlat, dlon) @@ -176,6 +172,7 @@ public boolean onPreDraw() { GlideApp.with(context) .load(map.toString()) .error(R.drawable.placeholder) + .optionalCenterCrop() .into(holder.map_view); holder.map_view.getViewTreeObserver().removeOnPreDrawListener(this); return true; @@ -183,30 +180,29 @@ public boolean onPreDraw() { }); } + if (launchItem.getProbability() != null && launchItem.getProbability() > 0) { + holder.contentForecast.setText(String.format("%s%%", launchItem.getProbability())); + holder.forecast_container.setVisibility(View.VISIBLE); + } else { + holder.forecast_container.setVisibility(View.GONE); + } + switch (launchItem.getStatus()) { case 1: - String go = context.getResources().getString(R.string.status_go); - if (launchItem.getProbability() != null && launchItem.getProbability() > 0) { - go = String.format("%s | Forecast - %s%%", go, launchItem.getProbability()); - } //GO for launch - holder.content_status.setText(go); - holder.content_status.setTextColor(ContextCompat.getColor(context, R.color.colorGo)); + holder.content_status.setText(R.string.status_go); break; case 2: //NO GO for launch holder.content_status.setText(R.string.status_nogo); - holder.content_status.setTextColor(ContextCompat.getColor(context, R.color.colorAccent)); break; case 3: //Success for launch holder.content_status.setText(R.string.status_success); - holder.content_status.setTextColor(ContextCompat.getColor(context, R.color.colorGo)); break; case 4: //Failure to launch holder.content_status.setText(R.string.status_failure); - holder.content_status.setTextColor(ContextCompat.getColor(context, R.color.colorAccent)); break; } @@ -487,6 +483,8 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL public ImageView categoryIcon; public CountDownTimer timer; public View countdownView; + public View forecast_container; + public TextView contentForecast; public ImageView map_view; @@ -514,6 +512,9 @@ public ViewHolder(View view) { countdownSeconds = view.findViewById(R.id.countdown_seconds); countdownView = view.findViewById(R.id.countdown_layout); + forecast_container = view.findViewById(R.id.forecast_container); + contentForecast = view.findViewById(R.id.content_forecast); + map_view = view.findViewById(R.id.map_view); map_view.setClickable(false); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardSmallAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardSmallAdapter.java deleted file mode 100644 index 281474c83..000000000 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardSmallAdapter.java +++ /dev/null @@ -1,518 +0,0 @@ -package me.calebjones.spacelaunchnow.ui.main.next; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.Typeface; -import android.net.Uri; -import android.os.CountDownTimer; -import android.preference.PreferenceManager; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.RecyclerView; -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 com.afollestad.materialdialogs.MaterialDialog; -import com.afollestad.materialdialogs.simplelist.MaterialSimpleListItem; -import com.crashlytics.android.Crashlytics; - -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; - -import io.realm.RealmList; -import me.calebjones.spacelaunchnow.R; -import me.calebjones.spacelaunchnow.content.database.ListPreferences; -import me.calebjones.spacelaunchnow.content.util.DialogAdapter; -import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; -import me.calebjones.spacelaunchnow.data.models.realm.RealmStr; -import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; -import me.calebjones.spacelaunchnow.utils.Utils; -import timber.log.Timber; - -/** - * Adapts UpcomingLaunch data to the LaunchFragment - */ -public class CardSmallAdapter extends RecyclerView.Adapter { - public int position; - private String launchDate; - private RealmList launchList; - private Context mContext; - private Calendar rightNow; - private SharedPreferences sharedPref; - private Boolean night; - private static ListPreferences sharedPreference; - private int nightColor; - private int color; - private int accentColor; - - public CardSmallAdapter(Context context) { - rightNow = Calendar.getInstance(); - launchList = new RealmList<>(); - this.mContext = context; - nightColor = ContextCompat.getColor(context, R.color.dark_theme_secondary_text_color); - color = ContextCompat.getColor(context, R.color.colorTextSecondary); - accentColor = ContextCompat.getColor(context, R.color.colorAccent); - } - - public void addItems(List launchList) { - if (this.launchList != null) { - this.launchList.addAll(launchList); - } else { - this.launchList = new RealmList<>(); - this.launchList.addAll(launchList); - } - this.notifyDataSetChanged(); - } - - public void clearData() { - int size = this.launchList.size(); - if (size > 0) { - for (int i = 0; i < size; i++) { - this.launchList.remove(0); - } - - this.notifyItemRangeRemoved(0, size); - } - } - - public void clear() { - if (launchList != null) { - launchList.clear(); - this.notifyDataSetChanged(); - } - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { - - int m_theme; - - this.sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext); - sharedPreference = ListPreferences.getInstance(mContext); - - if (sharedPreference.isNightModeActive(mContext)) { - night = true; - } else { - night = false; - } - View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.small_content_card_item, viewGroup, false); - return new ViewHolder(v); - } - - @Override - public void onBindViewHolder(final ViewHolder holder, int i) { - final Launch launchItem = launchList.get(i); - - position = i; - - try { - //Retrieve missionType - if (launchItem.getMissions().size() != 0) { - Utils.setCategoryIcon(holder.categoryIcon, launchItem.getMissions().get(0).getTypeName(), night); - } else { - if (night) { - holder.categoryIcon.setImageResource(R.drawable.ic_unknown_white); - } else { - holder.categoryIcon.setImageResource(R.drawable.ic_unknown); - } - } - - SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); - df.toLocalizedPattern(); - - switch (launchItem.getStatus()) { - case 1: - //GO for launch - holder.content_status.setText(R.string.status_go); - holder.content_status.setTextColor(ContextCompat.getColor(mContext, R.color.colorGo)); - break; - case 2: - //NO GO for launch - holder.content_status.setText(R.string.status_nogo); - holder.content_status.setTextColor(ContextCompat.getColor(mContext, R.color.colorAccent)); - break; - case 3: - //Success for launch - holder.content_status.setText(R.string.status_success); - holder.content_status.setTextColor(ContextCompat.getColor(mContext, R.color.colorGo)); - break; - case 4: - //Failure to launch - holder.content_status.setText(R.string.status_failure); - holder.content_status.setTextColor(ContextCompat.getColor(mContext, R.color.colorAccent)); - break; - } - - //If timestamp is available calculate TMinus and date. - if (launchItem.getNetstamp() > 0) { - long longdate = launchItem.getNetstamp(); - longdate = longdate * 1000; - final Date date = new Date(longdate); - - Calendar future = DateToCalendar(date); - Calendar now = rightNow; - - now.setTimeInMillis(System.currentTimeMillis()); - if (holder.timer != null) { - holder.timer.cancel(); - } - - final int status = launchItem.getStatus(); - final String hold = launchItem.getHoldreason(); - - holder.timer = new CountDownTimer(future.getTimeInMillis() - now.getTimeInMillis(), 1000) { - StringBuilder time = new StringBuilder(); - - @Override - public void onFinish() { - holder.content_TMinus_status.setTypeface(Typeface.DEFAULT); - if (night) { - holder.content_TMinus_status.setTextColor(nightColor); - } else { - holder.content_TMinus_status.setTextColor(color); - } - if (status == 1) { - holder.content_TMinus_status.setText("Watch Live webcast for up to date status."); - - } else { - if (hold != null && hold.length() > 1) { - holder.content_TMinus_status.setText(hold); - } else { - holder.content_TMinus_status.setText("Watch Live webcast for up to date status."); - } - } - } - - @Override - public void onTick(long millisUntilFinished) { - time.setLength(0); - // Use days if appropriate - long longDays = millisUntilFinished / 86400000; - long longHours = (millisUntilFinished / 3600000) % 24; - long longMins = (millisUntilFinished / 60000) % 60; - long longSeconds = (millisUntilFinished / 1000) % 60; - - String days = String.valueOf(longDays); - String hours; - String minutes; - String seconds; - if (longHours < 10) { - hours = "0" + String.valueOf(longHours); - } else { - hours = String.valueOf(longHours); - } - - if (longMins < 10) { - minutes = "0" + String.valueOf(longMins); - } else { - minutes = String.valueOf(longMins); - } - - if (longSeconds < 10) { - seconds = "0" + String.valueOf(longSeconds); - } else { - seconds = String.valueOf(longSeconds); - } - holder.content_TMinus_status.setTypeface(Typeface.SANS_SERIF); - holder.content_TMinus_status.setTextColor(accentColor); - if (Integer.valueOf(days) > 0) { - holder.content_TMinus_status.setText(String.format("L - %s days - %s:%s:%s", days, hours, minutes, seconds)); - } else { - holder.content_TMinus_status.setText(String.format("L - %s:%s:%s", hours, minutes, seconds)); - } - } - }.start(); - - } else { - holder.content_TMinus_status.setTypeface(Typeface.DEFAULT); - if (night) { - holder.content_TMinus_status.setTextColor(ContextCompat.getColor(mContext, R.color.dark_theme_secondary_text_color)); - } else { - holder.content_TMinus_status.setTextColor(ContextCompat.getColor(mContext, R.color.colorTextSecondary)); - } - if (holder.timer != null) { - holder.timer.cancel(); - } - if (launchItem.getStatus() != 1) { - if (launchItem.getRocket().getAgencies().size() > 0) { - holder.content_TMinus_status.setText(String.format("Pending confirmed GO from %s", launchItem.getRocket().getAgencies().get(0).getName())); - } else { - holder.content_TMinus_status.setText("Pending confirmed GO for Launch from launch agency"); - } - } else { - holder.content_TMinus_status.setText("Unknown"); - } - } - - //Get launch date - if (launchItem.getStatus() == 2) { - - if (launchItem.getNet() != null) { - //Get launch date - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy."); - sdf.toLocalizedPattern(); - Date date = launchItem.getNet(); - launchDate = sdf.format(date); - holder.launch_date.setText("To be determined... " + launchDate); - } - } else { - if (launchItem.getNet() != null) { - if (sharedPref.getBoolean("local_time", true)) { - SimpleDateFormat sdf; - if (sharedPref.getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - HH:mm zzz"); - } else { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); - } - sdf.toLocalizedPattern(); - Date date = launchItem.getNet(); - launchDate = sdf.format(date); - } else { - SimpleDateFormat sdf; - if (sharedPref.getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - HH:mm zzz"); - } else { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); - } - Date date = launchItem.getNet(); - sdf.setTimeZone(TimeZone.getTimeZone("UTC")); - launchDate = sdf.format(date); - } - } else { - launchDate = "To be determined... "; - } - holder.launch_date.setText(launchDate); - } - - //If location is available then see if pad and agency informaiton is avaialble. - if (launchItem.getLocation().getName() != null) { - holder.location.setText(launchItem.getLocation().getName()); - } - holder.title.setText(launchItem.getRocket().getName()); - } catch (NullPointerException e) { - Crashlytics.logException(e); - } - } - - @Override - public int getItemCount() { - return launchList.size(); - } - - public static Calendar DateToCalendar(Date date) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - return cal; - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - public TextView title; - public TextView content; - public TextView location; - public TextView content_status; - public TextView launch_date; - public TextView content_TMinus_status; - public TextView watchButton; - public TextView exploreButton; - public ImageView categoryIcon; - public LinearLayout content_mission_description_view; - public CountDownTimer timer; - - //Add content to the card - public ViewHolder(View view) { - super(view); - - content_status = (TextView) view.findViewById(R.id.content_status); - categoryIcon = (ImageView) view.findViewById(R.id.categoryIcon); - exploreButton = (TextView) view.findViewById(R.id.exploreButton); - watchButton = (TextView) view.findViewById(R.id.watchButton); - title = (TextView) view.findViewById(R.id.launch_rocket); - location = (TextView) view.findViewById(R.id.location); - launch_date = (TextView) view.findViewById(R.id.launch_date); - content_TMinus_status = (TextView) view.findViewById(R.id.content_TMinus_status); - content_mission_description_view = (LinearLayout) view.findViewById(R.id.content_mission_description_view); - - exploreButton.setOnClickListener(this); - watchButton.setOnClickListener(this); - } - - //React to click events. - @Override - public void onClick(View v) { - final int position = getAdapterPosition(); - Timber.d("onClick at %s", position); - - final Launch launch = launchList.get(position); - - SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); - df.toLocalizedPattern(); - - switch (v.getId()) { - case R.id.watchButton: - Timber.d("Watch: %s", launch.getVidURLs().size()); - if (launch.getVidURLs().size() > 0) { - final DialogAdapter adapter = new DialogAdapter(new DialogAdapter.Callback() { - - @Override - public void onListItemSelected(int index, MaterialSimpleListItem item, boolean longClick) { - if (longClick) { - Intent sendIntent = new Intent(); - sendIntent.setAction(Intent.ACTION_SEND); - sendIntent.putExtra(Intent.EXTRA_TEXT, launch.getVidURLs().get(index).getVal()); // Simple text and URL to share - sendIntent.setType("text/plain"); - mContext.startActivity(sendIntent); - } else { - Uri watchUri = Uri.parse(launch.getVidURLs().get(index).getVal()); - Intent i = new Intent(Intent.ACTION_VIEW, watchUri); - mContext.startActivity(i); - } - } - }); - for (RealmStr s : launch.getVidURLs()) { - //Do your stuff here - adapter.add(new MaterialSimpleListItem.Builder(mContext) - .content(s.getVal()) - .build()); - } - - MaterialDialog.Builder builder = new MaterialDialog.Builder(mContext) - .title("Select a Source") - .content("Long press for additional options.") - .adapter(adapter, null) - .negativeText("Cancel"); - builder.show(); - } - break; - case R.id.exploreButton: - Timber.d("Explore: %s", launchList.get(position).getId()); - Intent exploreIntent = new Intent(mContext, LaunchDetailActivity.class); - exploreIntent.putExtra("TYPE", "launch"); - exploreIntent.putExtra("launchID", launch.getId()); - mContext.startActivity(exploreIntent); - break; - } - } - } - - private void setCategoryIcon(ViewHolder holder, String type) { - if (type != null) { - switch (type) { - case "Earth Science": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_earth_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_earth)); - } - break; - case "Planetary Science": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_planetary_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_planetary)); - } - break; - case "Astrophysics": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_astrophysics_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_astrophysics)); - } - break; - case "Heliophysics": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_heliophysics_alt_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_heliophysics_alt)); - } - break; - case "Human Exploration": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_human_explore_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_human_explore)); - } - break; - case "Robotic Exploration": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_robotic_explore_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_robotic_explore)); - } - break; - case "Government/Top Secret": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_top_secret_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_top_secret)); - } - break; - case "Tourism": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_tourism_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_tourism)); - } - break; - case "Unknown": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_unknown_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_unknown)); - } - break; - case "Communications": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_satellite_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_satellite)); - } - break; - case "Resupply": - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_resupply_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_resupply)); - } - break; - default: - if (night) { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_unknown_white)); - } else { - holder.categoryIcon.setImageDrawable( - ContextCompat.getDrawable(mContext, R.drawable.ic_unknown)); - } - break; - } - } - } -} diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java index cce6ce462..75bf6b86d 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java @@ -92,7 +92,6 @@ public class NextLaunchFragment extends BaseFragment implements SwipeRefreshLayo private View view; private RecyclerView mRecyclerView; private CardBigAdapter adapter; - private CardSmallAdapter smallAdapter; private StaggeredGridLayoutManager layoutManager; private LinearLayoutManager linearLayoutManager; private SwipeRefreshLayout mSwipeRefreshLayout; @@ -109,7 +108,6 @@ public class NextLaunchFragment extends BaseFragment implements SwipeRefreshLayo private boolean active; private boolean switchChanged; - private boolean cardSizeSmall; private CalendarSyncManager calendarSyncManager; @Override @@ -129,15 +127,12 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, active = false; sharedPref = PreferenceManager.getDefaultSharedPreferences(context); - cardSizeSmall = sharedPref.getBoolean("card_size_small", false); - if (cardSizeSmall) { - smallAdapter = new CardSmallAdapter(getActivity()); - } else { - if (adapter == null) { - adapter = new CardBigAdapter(getActivity()); - } + + if (adapter == null) { + adapter = new CardBigAdapter(getActivity()); } + if (sharedPreference.isNightModeActive(context)) { color = R.color.darkPrimary; } else { @@ -210,24 +205,15 @@ public void onScrollStateChanged(RecyclerView recyclerView, int newState) { }); //If preference is for small card, landscape tablets get three others get two. - if (cardSizeSmall) { - if (getResources().getBoolean(R.bool.landscape) && getResources().getBoolean(R.bool.isTablet)) { - layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL); - } else { - layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); - } + if (getResources().getBoolean(R.bool.landscape) && getResources().getBoolean(R.bool.isTablet)) { + layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(layoutManager); - mRecyclerView.setAdapter(smallAdapter); } else { - if (getResources().getBoolean(R.bool.landscape) && getResources().getBoolean(R.bool.isTablet)) { - layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); - mRecyclerView.setLayoutManager(layoutManager); - } else { - linearLayoutManager = new LinearLayoutManager(context.getApplicationContext(), LinearLayoutManager.VERTICAL, false); - mRecyclerView.setLayoutManager(linearLayoutManager); - } - mRecyclerView.setAdapter(adapter); + linearLayoutManager = new LinearLayoutManager(context.getApplicationContext(), LinearLayoutManager.VERTICAL, false); + mRecyclerView.setLayoutManager(linearLayoutManager); } + mRecyclerView.setAdapter(adapter); + coordinatorLayout = (CoordinatorLayout) view.findViewById(R.id.coordinatorLayout); @@ -263,28 +249,18 @@ public void onChange(RealmResults results) { Timber.v("Data changed - size: %s", results.size()); int preferredCount = Integer.parseInt(sharedPref.getString("upcoming_value", "5")); - if (cardSizeSmall) { - smallAdapter.clear(); - } else { - adapter.clear(); - } + adapter.clear(); if (results.size() >= preferredCount) { no_data.setVisibility(View.GONE); setLayoutManager(preferredCount); - if (cardSizeSmall) { - smallAdapter.addItems(results.subList(0, preferredCount)); - } else { - adapter.addItems(results.subList(0, preferredCount)); - } + adapter.addItems(results.subList(0, preferredCount)); + } else if (results.size() > 0) { no_data.setVisibility(View.GONE); setLayoutManager(preferredCount); - if (cardSizeSmall) { - smallAdapter.addItems(results); - } else { - adapter.addItems(results); - } + adapter.addItems(results); + } else { if (adapter != null) { adapter.clear(); @@ -306,7 +282,7 @@ public void displayLaunches() { if (switchPreferences.getAllSwitch()) { RealmQuery query = getRealm().where(Launch.class) .greaterThanOrEqualTo("net", date); - if(switchPreferences.getNoGoSwitch()){ + if (switchPreferences.getNoGoSwitch()) { query.equalTo("status", 1); } launchRealms = query.findAllSortedAsync("net", Sort.ASCENDING); @@ -322,22 +298,14 @@ private void setLayoutManager(int size) { if (!isDetached() && isAdded()) { if (getResources().getBoolean(R.bool.landscape) && getResources().getBoolean(R.bool.isTablet) && (launchRealms != null && launchRealms.size() == 1 || size == 1)) { linearLayoutManager = new LinearLayoutManager(context.getApplicationContext(), - LinearLayoutManager.VERTICAL, false + LinearLayoutManager.VERTICAL, false ); mRecyclerView.setLayoutManager(linearLayoutManager); - if (cardSizeSmall) { - mRecyclerView.setAdapter(smallAdapter); - } else { - mRecyclerView.setAdapter(adapter); - } + mRecyclerView.setAdapter(adapter); } else if (getResources().getBoolean(R.bool.landscape) && getResources().getBoolean(R.bool.isTablet)) { layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(layoutManager); - if (cardSizeSmall) { - mRecyclerView.setAdapter(smallAdapter); - } else { - mRecyclerView.setAdapter(adapter); - } + mRecyclerView.setAdapter(adapter); } } else if (isDetached()) { Timber.v("View is detached."); diff --git a/mobile/src/main/res/layout-large-port/content_card_item.xml b/mobile/src/main/res/layout-large-port/content_card_item.xml deleted file mode 100644 index b1425d9fb..000000000 --- a/mobile/src/main/res/layout-large-port/content_card_item.xml +++ /dev/null @@ -1,264 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mobile/src/main/res/layout/content_card_item.xml b/mobile/src/main/res/layout/content_card_item.xml index 5e9a4bf69..497abb992 100644 --- a/mobile/src/main/res/layout/content_card_item.xml +++ b/mobile/src/main/res/layout/content_card_item.xml @@ -4,6 +4,8 @@ xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="fill_parent" android:layout_height="wrap_content" + android:paddingBottom="@dimen/material_baseline_grid_1x" + android:paddingTop="@dimen/material_baseline_grid_1x" android:textAlignment="center" android:transitionGroup="true"> @@ -11,13 +13,16 @@ android:id="@+id/card_view" android:layout_width="fill_parent" android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/material_baseline_grid_0.5x" android:layout_marginLeft="@dimen/card_margin" android:layout_marginRight="@dimen/card_margin" android:animateLayoutChanges="true" - card_view:cardCornerRadius="0dp" + android:paddingBottom="@dimen/material_baseline_grid_0.5x" + android:paddingTop="@dimen/material_baseline_grid_0.5x" + card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" card_view:cardPreventCornerOverlap="true" - card_view:cardUseCompatPadding="true"> + card_view:cardUseCompatPadding="false"> @@ -38,7 +44,7 @@ android:layout_height="100dp" android:layout_gravity="center" android:padding="16dp" - app:srcCompat="@drawable/ic_unknown" /> + app:srcCompat="@drawable/ic_unknown_white" /> @@ -69,10 +74,9 @@ android:ellipsize="end" android:gravity="left" android:maxLines="2" - android:padding="2dp" - android:textColor="?android:textColorSecondary" android:singleLine="false" - android:text="Unknown Launch Location" /> + android:text="Unknown Launch Location" + android:textColor="?android:textColorSecondaryInverse" /> + android:text="Unknown Launch Date" + android:textColor="?android:textColorSecondaryInverse" /> - - + - + + - - - - - - - - + android:orientation="vertical" + android:paddingBottom="4dp" + android:paddingLeft="28dp" + android:paddingRight="28dp" + android:paddingTop="8dp"> + @@ -196,6 +176,36 @@ android:padding="12dp" android:paddingBottom="8dp" /> + + + + + + + + - - + android:paddingBottom="4dp"> - - - + android:orientation="vertical" + android:paddingBottom="4dp" + android:paddingLeft="28dp" + android:paddingRight="28dp" + android:paddingTop="8dp"> - + + + + @@ -165,13 +162,13 @@ + android:text="Launch Notifications" + android:visibility="gone" /> diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index cbe390171..3f58bec52 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -3,10 +3,10 @@ Open navigation drawer Close navigation drawer Settings - "Launch is GO" + "Go for Launch" "Launch is NO GO" - "Successful Launch" - "Launch Failure" + "Launch was Successful" + "Launch Failure Occurred" Settings Settings SpaceX designs, manufactures and launches advanced rockets and spacecraft. The company was founded in 2002 to revolutionize space technology, with the ultimate goal of enabling people to live on other planets. diff --git a/mobile/src/main/res/xml/appearance_preferences.xml b/mobile/src/main/res/xml/appearance_preferences.xml index 9b486e678..9456c6de8 100644 --- a/mobile/src/main/res/xml/appearance_preferences.xml +++ b/mobile/src/main/res/xml/appearance_preferences.xml @@ -14,12 +14,6 @@ android:summaryOff="Launch times in AM/PM." android:summaryOn="Launch times in 24 hour." android:title="Time Format" /> - Date: Sat, 16 Dec 2017 02:36:43 -0500 Subject: [PATCH 06/41] Add accent colors --- .idea/markdown-exported-files.xml | 8 ++ build.gradle | 6 +- mobile/src/main/assets/CHANGELOG.md | 11 +- .../fragments/AgencyDetailFragment.java | 1 - .../layout-w500dp/detail_launch_agency.xml | 38 +++--- .../layout-w500dp/detail_launch_payload.xml | 31 +++-- .../layout-w500dp/detail_launch_summary.xml | 63 +++++----- .../src/main/res/layout/content_card_item.xml | 44 ++++--- .../main/res/layout/detail_launch_agency.xml | 114 ++++++++---------- .../main/res/layout/detail_launch_payload.xml | 32 +++-- .../main/res/layout/detail_launch_summary.xml | 12 +- .../src/main/res/values-night-v21/themes.xml | 2 +- mobile/src/main/res/values-night/themes.xml | 1 + mobile/src/main/res/values-v21/styles.xml | 1 + mobile/src/main/res/values/attrs.xml | 2 + mobile/src/main/res/values/colors.xml | 2 +- mobile/src/main/res/values/styles.xml | 1 + mobile/version.properties | 2 +- wear/version.properties | 2 +- 19 files changed, 176 insertions(+), 197 deletions(-) create mode 100644 .idea/markdown-exported-files.xml diff --git a/.idea/markdown-exported-files.xml b/.idea/markdown-exported-files.xml new file mode 100644 index 000000000..5d1f1293c --- /dev/null +++ b/.idea/markdown-exported-files.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 09884a562..38336828f 100644 --- a/build.gradle +++ b/build.gradle @@ -34,9 +34,9 @@ task clean(type: Delete) { ext { app = [ - versionMajor : 1, - versionMinor : 8, - versionPatch : 1 + versionMajor : 2, + versionMinor : 0, + versionPatch : 0 ] // Sdk and tools minSdkVersion = 15 diff --git a/mobile/src/main/assets/CHANGELOG.md b/mobile/src/main/assets/CHANGELOG.md index 830bddc15..f912b6c95 100644 --- a/mobile/src/main/assets/CHANGELOG.md +++ b/mobile/src/main/assets/CHANGELOG.md @@ -5,7 +5,16 @@ A space launch tracker for Android using data from the Launch Library API. ## Changelog #### Updated 11-25-2017 --- -### Version 1.8.1 (Latest) +### Version 2.0.0 (Latest) +#### Overview +Just a few bug-fixes and cleanups from the previous release. + +#### Changelog +* Overhauled style of the main UI workflow's. +* Used the Google Palette library to generate accent colors everywhere I could. +* Reworked Vehicle launch data. +--- +### Version 1.8.1 #### Overview Just a few bug-fixes and cleanups from the previous release. diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java index 963e86a37..ee82ac2f0 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java @@ -23,7 +23,6 @@ import me.calebjones.spacelaunchnow.common.BaseFragment; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.events.LaunchEvent; -import me.calebjones.spacelaunchnow.data.models.VehicleDetails; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; diff --git a/mobile/src/main/res/layout-w500dp/detail_launch_agency.xml b/mobile/src/main/res/layout-w500dp/detail_launch_agency.xml index ef4d58aa7..71dd3caa9 100644 --- a/mobile/src/main/res/layout-w500dp/detail_launch_agency.xml +++ b/mobile/src/main/res/layout-w500dp/detail_launch_agency.xml @@ -1,5 +1,6 @@ - + android:elevation="4dp" + android:background="?attr/titleBarColor"> @@ -60,7 +63,7 @@ android:singleLine="false" android:text="Unknown" android:textAlignment="center" - android:textColor="?android:textColorSecondary" + android:textColor="@color/dark_secondary_text_color_selector" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> @@ -70,15 +73,9 @@ android:layout_height="match_parent" android:orientation="vertical" android:padding="@dimen/material_baseline_grid_0.5x" + android:elevation="2dp" android:weightSum="1"> - + android:elevation="4dp" + android:background="?attr/titleBarColor"> @@ -280,7 +277,7 @@ android:singleLine="false" android:text="Unknown" android:textAlignment="center" - android:textColor="?android:textColorSecondary" + android:textColor="@color/dark_secondary_text_color_selector" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> @@ -292,13 +289,6 @@ android:padding="@dimen/material_baseline_grid_0.5x" android:orientation="vertical"> - - + android:orientation="vertical"> + android:orientation="vertical"> - - - - - - - - - + android:ellipsize="end" + android:gravity="center" + android:elevation="4dp" + android:paddingBottom="8dp" + android:paddingTop="4dp" + android:singleLine="false" + android:text="Unknown Launch Status" + android:textAlignment="center" + android:background="?attr/titleBarColor" + android:textColor="@color/dark_primary_text_color_selector" + android:textSize="20sp" + android:textStyle="bold" /> - + + + android:textAppearance="@style/MaterialTypography.Regular.Subheading"/> + android:text="Launch Notifications" + android:visibility="gone" /> @@ -62,7 +62,7 @@ android:gravity="left" android:maxLines="2" android:text="Unknown Launch Vehicle" - android:textColor="?android:textColorPrimaryInverse" + android:textColor="@color/dark_primary_text_color_selector" android:textSize="18sp" android:textStyle="normal" /> @@ -76,7 +76,7 @@ android:maxLines="2" android:singleLine="false" android:text="Unknown Launch Location" - android:textColor="?android:textColorSecondaryInverse" /> + android:textColor="@color/dark_secondary_text_color_selector" /> + android:textColor="@color/dark_secondary_text_color_selector" /> @@ -100,29 +100,28 @@ android:layout_height="160dp" android:contentDescription="A map view of launch location." /> - - + android:textColor="@color/dark_primary_text_color_selector" + android:textSize="20sp" + android:textStyle="bold" /> - + @@ -161,7 +160,6 @@ android:id="@+id/content_mission_description_view" android:layout_width="match_parent" android:layout_height="match_parent" - android:elevation="4dp" android:orientation="vertical" android:paddingBottom="8dp"> diff --git a/mobile/src/main/res/layout/detail_launch_agency.xml b/mobile/src/main/res/layout/detail_launch_agency.xml index 7201767ae..46959737a 100644 --- a/mobile/src/main/res/layout/detail_launch_agency.xml +++ b/mobile/src/main/res/layout/detail_launch_agency.xml @@ -19,8 +19,8 @@ + android:elevation="4dp" + android:background="?attr/titleBarColor" + android:orientation="vertical"> @@ -56,13 +56,14 @@ android:id="@+id/mission_agency_type" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/titleBarColor" android:ellipsize="end" android:gravity="center" android:lines="1" android:singleLine="false" android:text="Unknown" android:textAlignment="center" - android:textColor="?android:textColorSecondary" + android:textColor="@color/dark_secondary_text_color_selector" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> @@ -71,16 +72,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:padding="@dimen/material_baseline_grid_0.5x" android:weightSum="1"> - @@ -125,9 +118,9 @@ + android:padding="@dimen/material_baseline_grid_0.5x"> - + android:orientation="horizontal" + android:padding="@dimen/material_baseline_grid_0.5x"> - - - - - + android:elevation="4dp" + android:orientation="vertical" + android:background="?attr/titleBarColor"> - + + + + + - diff --git a/mobile/src/main/res/layout/detail_launch_payload.xml b/mobile/src/main/res/layout/detail_launch_payload.xml index 71a69eb0b..b2017d5c5 100644 --- a/mobile/src/main/res/layout/detail_launch_payload.xml +++ b/mobile/src/main/res/layout/detail_launch_payload.xml @@ -28,8 +28,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" - android:paddingLeft="8dp"> + android:orientation="vertical"> + + android:orientation="vertical"> - - @@ -112,9 +115,8 @@ android:paddingTop="8dp" android:text="Estimated Launch Date" android:textAlignment="center" - android:textColor="?android:textColorPrimary" android:textSize="18sp" - android:textStyle="bold" /> + android:textAppearance="@style/MaterialTypography.Regular.Subheading"/> @color/darkPrimary @color/darkPrimary_dark @color/darkAccent - + @color/darkPrimary @color/materialGrey @color/cardview_dark_background @color/darkPrimary_dark diff --git a/mobile/src/main/res/values-night/themes.xml b/mobile/src/main/res/values-night/themes.xml index cc3698e41..b5f18253f 100644 --- a/mobile/src/main/res/values-night/themes.xml +++ b/mobile/src/main/res/values-night/themes.xml @@ -5,6 +5,7 @@ @color/darkPrimary @color/darkPrimary_dark @color/darkAccent + @color/darkPrimary @color/darkIcons @color/cardview_dark_background diff --git a/mobile/src/main/res/values-v21/styles.xml b/mobile/src/main/res/values-v21/styles.xml index c960eb8a4..f6539be59 100644 --- a/mobile/src/main/res/values-v21/styles.xml +++ b/mobile/src/main/res/values-v21/styles.xml @@ -4,6 +4,7 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent + @color/colorAccent @android:color/white @color/materialGrey #212121 diff --git a/mobile/src/main/res/values/attrs.xml b/mobile/src/main/res/values/attrs.xml index fe5a06498..6bcf7c71d 100644 --- a/mobile/src/main/res/values/attrs.xml +++ b/mobile/src/main/res/values/attrs.xml @@ -21,4 +21,6 @@ + + diff --git a/mobile/src/main/res/values/colors.xml b/mobile/src/main/res/values/colors.xml index 0369b7b1e..892dc8468 100644 --- a/mobile/src/main/res/values/colors.xml +++ b/mobile/src/main/res/values/colors.xml @@ -28,7 +28,7 @@ #b3ffffff #ff303030 #424242 - #ff455a64 + #455a64 #ff37474f #F44336 #ffffffff diff --git a/mobile/src/main/res/values/styles.xml b/mobile/src/main/res/values/styles.xml index dae096680..81a1e7dae 100644 --- a/mobile/src/main/res/values/styles.xml +++ b/mobile/src/main/res/values/styles.xml @@ -34,6 +34,7 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent + @color/colorAccent #212121 #757575 diff --git a/mobile/version.properties b/mobile/version.properties index 0d67edf92..cb7017721 100644 --- a/mobile/version.properties +++ b/mobile/version.properties @@ -1,2 +1,2 @@ #Wed Dec 13 13:36:36 EST 2017 -AI_VERSION_CODE=1017 +AI_VERSION_CODE=1 diff --git a/wear/version.properties b/wear/version.properties index 56d2ae274..eec62fc4a 100644 --- a/wear/version.properties +++ b/wear/version.properties @@ -1,2 +1,2 @@ #Wed Dec 13 13:36:37 EST 2017 -AI_VERSION_CODE=1017 +AI_VERSION_CODE=1 From 4a2b65ed27648234704ce170b1fd723536bea117 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Sat, 16 Dec 2017 02:39:26 -0500 Subject: [PATCH 07/41] WIP --- .../res/layout-w500dp/content_card_item.xml | 280 ++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 mobile/src/main/res/layout-w500dp/content_card_item.xml diff --git a/mobile/src/main/res/layout-w500dp/content_card_item.xml b/mobile/src/main/res/layout-w500dp/content_card_item.xml new file mode 100644 index 000000000..172e270ef --- /dev/null +++ b/mobile/src/main/res/layout-w500dp/content_card_item.xml @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From a59b4b0e1390306d4951a64fb1e11555f886368a Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Sun, 17 Dec 2017 23:04:19 -0500 Subject: [PATCH 08/41] UI - overhaul --- .../res/layout-w500dp/content_card_item.xml | 4 -- .../layout-w500dp/detail_launch_agency.xml | 3 - .../layout-w500dp/detail_launch_payload.xml | 6 +- .../layout-w500dp/detail_launch_summary.xml | 2 - .../src/main/res/layout/content_card_item.xml | 4 -- .../main/res/layout/detail_launch_agency.xml | 62 ++++++++++++------- .../main/res/layout/detail_launch_payload.xml | 4 -- .../main/res/layout/detail_launch_summary.xml | 2 - .../src/main/res/layout/vehicle_list_item.xml | 2 +- 9 files changed, 42 insertions(+), 47 deletions(-) diff --git a/mobile/src/main/res/layout-w500dp/content_card_item.xml b/mobile/src/main/res/layout-w500dp/content_card_item.xml index 172e270ef..5d963c959 100644 --- a/mobile/src/main/res/layout-w500dp/content_card_item.xml +++ b/mobile/src/main/res/layout-w500dp/content_card_item.xml @@ -36,7 +36,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/titleBarColor" - android:elevation="4dp" android:orientation="horizontal"> @@ -209,7 +207,6 @@ android:id="@+id/content_mission" android:layout_width="match_parent" android:layout_height="wrap_content" - android:elevation="0dp" android:paddingLeft="28dp" android:paddingRight="28dp" android:text="Unknown Mission" @@ -231,7 +228,6 @@ @@ -252,7 +250,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:elevation="4dp" android:background="?attr/titleBarColor"> @@ -49,7 +48,6 @@ android:layout_height="wrap_content" android:ellipsize="end" android:gravity="center" - android:elevation="4dp" android:paddingBottom="8dp" android:paddingTop="4dp" android:singleLine="false" diff --git a/mobile/src/main/res/layout/content_card_item.xml b/mobile/src/main/res/layout/content_card_item.xml index ed50b4e17..1e6d32914 100644 --- a/mobile/src/main/res/layout/content_card_item.xml +++ b/mobile/src/main/res/layout/content_card_item.xml @@ -35,7 +35,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/titleBarColor" - android:elevation="4dp" android:orientation="horizontal"> @@ -208,7 +206,6 @@ android:id="@+id/content_mission" android:layout_width="match_parent" android:layout_height="wrap_content" - android:elevation="0dp" android:paddingLeft="28dp" android:paddingRight="28dp" android:text="Unknown Mission" @@ -230,7 +227,6 @@ @@ -61,7 +60,6 @@ android:gravity="center" android:lines="1" android:singleLine="false" - android:text="Unknown" android:textAlignment="center" android:textColor="@color/dark_secondary_text_color_selector" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> @@ -81,13 +79,14 @@ android:layout_height="wrap_content" android:ellipsize="end" android:gravity="start" - android:lines="1" - android:paddingBottom="@dimen/material_card_supporting_text_padding_bottom" + android:maxLines="2" + android:paddingBottom="@dimen/material_baseline_grid_0.5x" android:paddingLeft="@dimen/material_card_supporting_text_padding_horizontal" android:paddingRight="@dimen/material_card_supporting_text_padding_horizontal" - android:layout_marginTop="@dimen/material_card_supporting_text_padding_top" + android:layout_marginTop="@dimen/material_baseline_grid_1x" android:text="Agency One" android:textColor="?android:textColorSecondary" + android:textAppearance="@style/MaterialTypography.Regular.Title" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> + android:textAppearance="@style/MaterialTypography.Regular.Caption" /> + + @@ -177,8 +187,8 @@ android:paddingLeft="@dimen/material_card_supporting_text_padding_horizontal" android:paddingRight="@dimen/material_card_supporting_text_padding_horizontal" android:text="Unknown Agency Type" - android:textColor="?android:textColorSecondary" - android:textSize="@dimen/material_typography_regular_body_1_text_size" /> + android:textAppearance="@style/MaterialTypography.Regular.Caption" + android:textColor="?android:textColorSecondary" /> @@ -268,7 +278,7 @@ android:paddingBottom="2dp" android:lines="1" android:singleLine="false" - android:text="Unknown" + android:text="" android:textAlignment="center" android:textColor="@color/dark_secondary_text_color_selector" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> @@ -288,13 +298,14 @@ android:layout_height="wrap_content" android:ellipsize="end" android:gravity="start" - android:lines="1" - android:paddingBottom="@dimen/material_card_supporting_text_padding_bottom" + android:maxLines="2" + android:paddingBottom="@dimen/material_baseline_grid_0.5x" android:paddingLeft="@dimen/material_card_supporting_text_padding_horizontal" android:paddingRight="@dimen/material_card_supporting_text_padding_horizontal" android:layout_marginTop="@dimen/material_card_supporting_text_padding_top" android:text="Agency One" android:textColor="?android:textColorSecondary" + android:textAppearance="@style/MaterialTypography.Regular.Title" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> + android:textAppearance="@style/MaterialTypography.Regular.Caption" /> @@ -371,13 +384,14 @@ android:layout_height="wrap_content" android:ellipsize="end" android:gravity="start" - android:lines="1" - android:paddingBottom="@dimen/material_card_supporting_text_padding_bottom" + android:maxLines="2" + android:paddingBottom="@dimen/material_baseline_grid_0.5x" android:paddingLeft="@dimen/material_card_supporting_text_padding_horizontal" android:paddingRight="@dimen/material_card_supporting_text_padding_horizontal" - android:paddingTop="@dimen/material_card_supporting_text_padding_top" + android:paddingTop="@dimen/material_baseline_grid_1x" android:text="Agency Two" android:textColor="?android:textColorSecondary" + android:textAppearance="@style/MaterialTypography.Regular.Title" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> + android:textAppearance="@style/MaterialTypography.Regular.Caption" + /> From e35495f1af2698d080b576d35b7268d7015dc125 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Sun, 17 Dec 2017 23:49:42 -0500 Subject: [PATCH 09/41] Bug Fix --- .../calebjones/spacelaunchnow/LaunchApplication.java | 5 +---- .../calebjones/spacelaunchnow/utils/Connectivity.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/LaunchApplication.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/LaunchApplication.java index 10ab5c3bf..ade6587f8 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/LaunchApplication.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/LaunchApplication.java @@ -101,10 +101,7 @@ public void onCreate() { Crashlytics.setString("Language", Locale.getDefault().getDisplayLanguage()); Crashlytics.setBool("is24", DateFormat.is24HourFormat(getApplicationContext())); Crashlytics.setBool("Network State", Utils.isNetworkAvailable(this)); - - if (Connectivity.getNetworkInfo(this) != null) { - Crashlytics.setString("Network Info", Connectivity.getNetworkInfo(this).toString()); - } + Crashlytics.setString("Network Info", Connectivity.getNetworkStatus(this)); sharedPref = PreferenceManager.getDefaultSharedPreferences(this); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Connectivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Connectivity.java index e2991cec6..0c622086f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Connectivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Connectivity.java @@ -3,6 +3,7 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.os.Build; import android.telephony.TelephonyManager; /** @@ -22,6 +23,16 @@ public static NetworkInfo getNetworkInfo(Context context){ return cm.getActiveNetworkInfo(); } + public static String getNetworkStatus(Context context){ + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm != null && cm.getActiveNetworkInfo() != null){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return cm.getActiveNetwork().toString(); + } + } + return "Unknown"; + } + /** * Check if there is any connectivity * @param context From b355d79fbdb5e188eb60b97c83657a05ce9eff2d Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Mon, 18 Dec 2017 09:02:56 -0500 Subject: [PATCH 10/41] Close realm instance after service --- .../spacelaunchnow/content/wear/WearWatchfaceManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/wear/WearWatchfaceManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/wear/WearWatchfaceManager.java index 11c7d775f..19d445b39 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/wear/WearWatchfaceManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/wear/WearWatchfaceManager.java @@ -91,6 +91,7 @@ public void updateWear() { } catch (IndexOutOfBoundsException error){ Crashlytics.logException(error); } + mRealm.close(); } private void sendImageToWear(String image, final Launch launch, boolean modify) { From 4fd8acfd94721209c968af2d0ecb1c4a6ce1d0b9 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Wed, 20 Dec 2017 20:56:15 -0500 Subject: [PATCH 11/41] Bump --- mobile/version.properties | 4 ++-- wear/version.properties | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mobile/version.properties b/mobile/version.properties index c1f113f33..f9994b3e6 100644 --- a/mobile/version.properties +++ b/mobile/version.properties @@ -1,2 +1,2 @@ -#Wed Dec 13 13:36:36 EST 2017 -AI_VERSION_CODE=1 \ No newline at end of file +#Mon Dec 18 09:57:57 EST 2017 +AI_VERSION_CODE=3 diff --git a/wear/version.properties b/wear/version.properties index eec62fc4a..a3dee10f1 100644 --- a/wear/version.properties +++ b/wear/version.properties @@ -1,2 +1,2 @@ -#Wed Dec 13 13:36:37 EST 2017 -AI_VERSION_CODE=1 +#Mon Dec 18 09:57:58 EST 2017 +AI_VERSION_CODE=3 From 4bcd695940d6dfdfcb0cd0847533d28a2b6e033a Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Thu, 21 Dec 2017 00:38:02 -0500 Subject: [PATCH 12/41] Alpha release. --- .../spacelaunchnow/data/models/Constants.java | 4 +- .../data/models/realm/Migration.java | 8 ++ .../models/spacelaunchnow/RocketDetail.java | 10 ++ mobile/src/main/assets/CHANGELOG.md | 9 +- .../content/data/DataSaver.java | 35 +----- .../content/services/LibraryDataManager.java | 3 - .../content/services/NextLaunchTracker.java | 4 +- .../fragments/MissionDetailFragment.java | 9 +- .../fragments/SummaryDetailFragment.java | 2 - .../ui/main/next/NextLaunchFragment.java | 110 +++++++++--------- .../wordtimer/LaunchWordTimerManager.java | 4 +- mobile/version.properties | 4 +- wear/version.properties | 4 +- 13 files changed, 93 insertions(+), 113 deletions(-) diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java index 729015c16..6de2fcef1 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java @@ -26,14 +26,14 @@ public final class Constants { public static final String ACTION_UPDATE_WORD_TIMER = "UPDATE_WORD_TIMER"; public static int NOTIF_ID = 568975; public static int NOTIF_ID_DAY = 568985; - public static int NOTIF_ID_HOUR = 568995; - public static int DB_SCHEMA_VERSION_1_5_5 = 188; + public static int DB_SCHEMA_VERSION_1_5_5 = 188; public static int DB_SCHEMA_VERSION_1_5_6 = 189; public static int DB_SCHEMA_VERSION_1_8_0 = 320; public static int DB_SCHEMA_VERSION_1_8_1 = 322; public static int DB_SCHEMA_VERSION_1_8_2 = 323; + public static int DB_SCHEMA_VERSION_2_0_0 = 324; public static String FORECAST_IO_BASE_URL = "https://api.forecast.io/"; public static String API_BASE_URL = "https://api.spacelaunchnow.me/"; diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java index 5ea604959..d7fcfce3c 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java @@ -120,6 +120,14 @@ public void apply(DynamicRealmObject obj) { oldVersion++; } + if (oldVersion <= Constants.DB_SCHEMA_VERSION_2_0_0) { + RealmObjectSchema details = schema.get("RocketDetail"); + if (details != null){ + details.addField("fullName", String.class); + } + oldVersion++; + } + Timber.i("Final Schema - Version %s", newVersion); for (RealmObjectSchema objectSchema : schema.getAll()) { Timber.d("Name: %s Fields: %s", objectSchema.getClassName(), objectSchema.getFieldNames()); diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java index 19d2f3806..4e127c010 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/spacelaunchnow/RocketDetail.java @@ -52,6 +52,8 @@ public class RocketDetail extends RealmObject { private String range; @SerializedName(value = "image_url") private String imageURL; + @SerializedName(value = "full_name") + private String fullName; public String getName() { return name; @@ -237,4 +239,12 @@ public int getId() { public void setId(int id) { this.id = id; } + + public String getFullName() { + return fullName; + } + + public void setFullName() { + this.fullName = this.name + " " + this.getVariant(); + } } diff --git a/mobile/src/main/assets/CHANGELOG.md b/mobile/src/main/assets/CHANGELOG.md index f912b6c95..824668f6f 100644 --- a/mobile/src/main/assets/CHANGELOG.md +++ b/mobile/src/main/assets/CHANGELOG.md @@ -7,12 +7,13 @@ A space launch tracker for Android using data from the Launch Library API. --- ### Version 2.0.0 (Latest) #### Overview -Just a few bug-fixes and cleanups from the previous release. +Color. Colors everywhere. Widgets. #### Changelog -* Overhauled style of the main UI workflow's. -* Used the Google Palette library to generate accent colors everywhere I could. -* Reworked Vehicle launch data. +* blah +* blah +* blah + --- ### Version 1.8.1 #### Overview diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataSaver.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataSaver.java index 326bf13b1..fdb294cf0 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataSaver.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/data/DataSaver.java @@ -121,12 +121,10 @@ public void execute(Realm mRealm) { Timber.v("Saving item: %s", item.getName()); mRealm.copyToRealmOrUpdate(item); } + mRealm.copyToRealmOrUpdate(Arrays.asList(launches)); } - - mRealm.copyToRealmOrUpdate(Arrays.asList(launches)); } }); - syncNotifiers(mRealm); mRealm.close(); isSaving = false; } @@ -140,35 +138,6 @@ private static boolean isLaunchTimeChanged(Launch previous, Launch item) { return false; } - public void syncNotifiers(Realm mRealm) { - isSyncing = true; - RealmResults launchRealms; - Date date = new Date(); - - SwitchPreferences switchPreferences = SwitchPreferences.getInstance(context); - - if (switchPreferences.getAllSwitch()) { - launchRealms = mRealm.where(Launch.class) - .greaterThanOrEqualTo("net", date) - .findAllSorted("net", Sort.ASCENDING); - } else { - launchRealms = QueryBuilder.buildSwitchQuery(context, mRealm); - } - - for (final Launch launchRealm : launchRealms) { - if (!launchRealm.isUserToggledNotifiable() && !launchRealm.isNotifiable()) { - mRealm.executeTransaction(new Realm.Transaction() { - @Override - public void execute(Realm realm) { - launchRealm.setNotifiable(true); - } - }); - } - } - mRealm.close(); - isSyncing = false; - } - public void sendResult(final Result result) { Intent broadcastIntent = new Intent(); broadcastIntent.setAction(result.getAction()); @@ -252,7 +221,6 @@ public void execute(Realm realm) { } } }); - syncNotifiers(mRealm); isSaving = false; mRealm.close(); } @@ -295,7 +263,6 @@ public void execute(Realm realm) { } } }); - syncNotifiers(mRealm); isSaving = false; mRealm.close(); } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/LibraryDataManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/LibraryDataManager.java index 89f78c272..773bea90d 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/LibraryDataManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/LibraryDataManager.java @@ -61,9 +61,6 @@ public void getVehicles(){ dataClientManager.getRocketFamily(); } - public void syncNotifiers() { - dataClientManager.getDataSaver().syncNotifiers(mRealm); - } public void updateNextLaunchMini() { Timber.v("Sending Update Next Launch intent."); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/NextLaunchTracker.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/NextLaunchTracker.java index f359605fe..4119897a3 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/NextLaunchTracker.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/NextLaunchTracker.java @@ -37,7 +37,7 @@ public void runUpdate() { SyncJob.schedulePeriodicJob(context); } - private void updateWidgets() { + public void updateWidgets() { LaunchCardCompactManager launchCardCompactManager = new LaunchCardCompactManager(context); LaunchWordTimerManager launchWordTimerManager = new LaunchWordTimerManager(context); int cardIds[] = AppWidgetManager.getInstance(context) @@ -57,7 +57,7 @@ private void updateWidgets() { } } - private void syncCalendar() { + public void syncCalendar() { CalendarSyncManager calendarSyncManager = new CalendarSyncManager(context); calendarSyncManager.syncAllEevnts(); } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java index d85b93a21..c3478ca87 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java @@ -32,8 +32,6 @@ public class MissionDetailFragment extends BaseFragment { - private SharedPreferences sharedPref; - private static ListPreferences sharedPreference; private Context context; public static Launch detailLaunch; private RocketDetail launchVehicle; @@ -80,11 +78,7 @@ public void onCreate(Bundle savedInstanceState) { @Override public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { View view; - this.sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - this.context = getContext(); - - sharedPreference = ListPreferences.getInstance(this.context); - + context = getContext(); view = inflater.inflate(R.layout.detail_launch_payload, container, false); detailLaunch = ((LaunchDetailActivity) getActivity()).getLaunch(); @@ -196,6 +190,7 @@ private void getLaunchVehicle(Launch vehicle) { query = vehicle.getRocket().getName(); } + // TODO change to pulling alias - if not exist check SLN API launchVehicle = getRealm().where(RocketDetail.class).contains("name", query).findFirst(); } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java index b463b644c..34710bd6b 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java @@ -618,8 +618,6 @@ public void execute(Realm realm) { Timber.v("Launch %s notifiable updated to %s", detailLaunch.getName(), detailLaunch.isNotifiable()); } }); - LibraryDataManager libraryDataManager = new LibraryDataManager(context); - libraryDataManager.syncNotifiers(); } }); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java index 75bf6b86d..60f03aafc 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java @@ -3,7 +3,9 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.TargetApi; +import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -47,7 +49,9 @@ import me.calebjones.spacelaunchnow.common.BaseFragment; import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; +import me.calebjones.spacelaunchnow.content.jobs.UpdateWearJob; import me.calebjones.spacelaunchnow.content.services.LibraryDataManager; +import me.calebjones.spacelaunchnow.content.services.NextLaunchTracker; import me.calebjones.spacelaunchnow.content.util.QueryBuilder; import me.calebjones.spacelaunchnow.data.models.Constants; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; @@ -56,6 +60,10 @@ import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.views.SnackbarHandler; import me.calebjones.spacelaunchnow.utils.Utils; +import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactManager; +import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactWidgetProvider; +import me.calebjones.spacelaunchnow.widget.wordtimer.LaunchWordTimerManager; +import me.calebjones.spacelaunchnow.widget.wordtimer.LaunchWordTimerWidgetProvider; import timber.log.Timber; public class NextLaunchFragment extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener { @@ -157,34 +165,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, FABMenu.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - setUpSwitches(); - if (!active) { - switchChanged = false; - active = true; - - mSwipeRefreshLayout.setEnabled(false); - FABMenu.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_close)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - showView(); - } else { - color_reveal.setVisibility(View.VISIBLE); - } - } else { - active = false; - FABMenu.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_filter)); - mSwipeRefreshLayout.setEnabled(true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - hideView(); - } else { - color_reveal.setVisibility(View.INVISIBLE); - } - if (switchChanged) { - displayLaunches(); - if (switchPreferences.getCalendarStatus()) { - calendarSyncManager.resyncAllEvents(); - } - } - } + checkFilter(); } }); @@ -537,36 +518,59 @@ public boolean onOptionsItemSelected(MenuItem item) { startActivity(debugIntent); } else if (id == R.id.action_alert) { - if (!active) { - Analytics.from(this).sendButtonClicked("Show Launch filters."); - switchChanged = false; - active = true; - mSwipeRefreshLayout.setEnabled(false); - FABMenu.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_close)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - showView(); - } else { - color_reveal.setVisibility(View.VISIBLE); - } + checkFilter(); + } + return super.onOptionsItemSelected(item); + } + + private void checkFilter() { + + if (!active) { + Analytics.from(this).sendButtonClicked("Show Launch filters."); + switchChanged = false; + active = true; + mSwipeRefreshLayout.setEnabled(false); + FABMenu.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_close)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + showView(); } else { - Analytics.from(this).sendButtonClicked("Hide Launch filters."); - active = false; - FABMenu.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_filter)); - mSwipeRefreshLayout.setEnabled(true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - hideView(); - } else { - color_reveal.setVisibility(View.INVISIBLE); + color_reveal.setVisibility(View.VISIBLE); + } + } else { + Analytics.from(this).sendButtonClicked("Hide Launch filters."); + active = false; + FABMenu.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_filter)); + mSwipeRefreshLayout.setEnabled(true); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + hideView(); + } else { + color_reveal.setVisibility(View.INVISIBLE); + } + if (switchChanged) { + LaunchCardCompactManager launchCardCompactManager = new LaunchCardCompactManager(context); + LaunchWordTimerManager launchWordTimerManager = new LaunchWordTimerManager(context); + int cardIds[] = AppWidgetManager.getInstance(context) + .getAppWidgetIds(new ComponentName(context, + LaunchCardCompactWidgetProvider.class)); + + for (int id : cardIds){ + launchCardCompactManager.updateAppWidget(id); } - if (switchChanged) { - displayLaunches(); - if (switchPreferences.getCalendarStatus()) { - calendarSyncManager.resyncAllEvents(); - } + + int timerIds[] = AppWidgetManager.getInstance(context) + .getAppWidgetIds(new ComponentName(context, + LaunchWordTimerWidgetProvider.class)); + + for (int id : timerIds){ + launchWordTimerManager.updateAppWidget(id); + } + UpdateWearJob.scheduleJobNow(); + displayLaunches(); + if (switchPreferences.getCalendarStatus()) { + calendarSyncManager.resyncAllEvents(); } } } - return super.onOptionsItemSelected(item); } @Override diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java index b47171426..8ef2baf3a 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java @@ -167,9 +167,9 @@ private void setWidgetStyle() { remoteViews.setInt(R.id.bgcolor, "setAlpha", widgetAlpha); remoteViews.setTextColor(R.id.widget_launch_name, widgetTextColor); remoteViews.setTextColor(R.id.widget_mission_name, widgetSecondaryTextColor); - remoteViews.setTextColor(R.id.countdown_days, widgetSecondaryTextColor); + remoteViews.setTextColor(R.id.countdown_days, widgetTextColor); remoteViews.setTextColor(R.id.countdown_days_label, widgetSecondaryTextColor); - remoteViews.setTextColor(R.id.countdown_hours, widgetSecondaryTextColor); + remoteViews.setTextColor(R.id.countdown_hours, widgetTextColor); remoteViews.setTextColor(R.id.countdown_hours_label, widgetSecondaryTextColor); remoteViews.setInt(R.id.widget_refresh_button, "setColorFilter", widgetIconColor); diff --git a/mobile/version.properties b/mobile/version.properties index c1f113f33..d9143ad2b 100644 --- a/mobile/version.properties +++ b/mobile/version.properties @@ -1,2 +1,2 @@ -#Wed Dec 13 13:36:36 EST 2017 -AI_VERSION_CODE=1 \ No newline at end of file +#Thu Dec 21 00:33:02 EST 2017 +AI_VERSION_CODE=3 diff --git a/wear/version.properties b/wear/version.properties index eec62fc4a..02d9e2356 100644 --- a/wear/version.properties +++ b/wear/version.properties @@ -1,2 +1,2 @@ -#Wed Dec 13 13:36:37 EST 2017 -AI_VERSION_CODE=1 +#Thu Dec 21 00:33:03 EST 2017 +AI_VERSION_CODE=3 From 65a5050541d5046c96c973135bf2cb3472950b38 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Thu, 21 Dec 2017 12:51:49 -0500 Subject: [PATCH 13/41] Commit --- wear/version.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/wear/version.properties b/wear/version.properties index eb6fa0ba5..f6d7f6f94 100644 --- a/wear/version.properties +++ b/wear/version.properties @@ -1 +1,2 @@ #Thu Dec 21 12:42:59 EST 2017 +AI_VERSION_CODE=5 From 08c9e342e58efbc8dd3e4e6115fa285f11fd1f36 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Thu, 21 Dec 2017 14:43:44 -0500 Subject: [PATCH 14/41] Next Launch Page --- .../data/models/launchlibrary/Launch.java | 8 +++ .../data/models/realm/Migration.java | 4 ++ .../ui/main/next/CardBigAdapter.java | 40 ++++++++---- .../res/layout-w500dp/content_card_item.xml | 27 ++++++-- .../layout-w500dp/detail_launch_agency.xml | 65 ++++++++++++------- .../layout-w500dp/detail_launch_payload.xml | 11 ++-- .../src/main/res/layout/content_card_item.xml | 28 ++++++-- .../main/res/layout/detail_launch_agency.xml | 14 +++- .../main/res/layout/detail_launch_payload.xml | 7 +- 9 files changed, 145 insertions(+), 59 deletions(-) diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launch.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launch.java index 9562938e3..af4d951d5 100755 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launch.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/launchlibrary/Launch.java @@ -36,6 +36,7 @@ public class Launch extends RealmObject { private Integer inhold; private Integer tbdtime; + private Integer tbddate; private Integer eventID; private Location location; @@ -365,4 +366,11 @@ public void setLsp(LSP lsp) { this.lsp = lsp; } + public Integer getTbddate() { + return tbddate; + } + + public void setTbddate(Integer tbddate) { + this.tbddate = tbddate; + } } diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java index d7fcfce3c..fd6cde134 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java @@ -125,6 +125,10 @@ public void apply(DynamicRealmObject obj) { if (details != null){ details.addField("fullName", String.class); } + RealmObjectSchema launch = schema.get("Launch"); + if (launch != null){ + launch.addField("tbddate", Integer.class); + } oldVersion++; } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java index 67c9924c5..ae30081df 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java @@ -52,7 +52,7 @@ public class CardBigAdapter extends RecyclerView.Adapter launchList; private Context context; private Calendar rightNow; @@ -361,39 +361,49 @@ public void onTick(long millisUntilFinished) { if (launchItem.getNet() != null) { //Get launch date - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy."); + SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); sdf.toLocalizedPattern(); Date date = launchItem.getNet(); - launchDate = sdf.format(date); - holder.launch_date.setText("To be determined... " + launchDate); + String launchTime = sdf.format(date); + if (launchItem.getTbddate() == 1){ + launchTime = launchTime + " (Unconfirmed)"; + } + holder.launch_date_compact.setText(launchTime); + holder.launch_time.setVisibility(View.GONE); } } else { if (launchItem.getNet() != null) { if (sharedPref.getBoolean("local_time", true)) { SimpleDateFormat sdf; if (sharedPref.getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - HH:mm zzz"); + sdf = new SimpleDateFormat("HH:mm zzz"); } else { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + sdf = new SimpleDateFormat("h:mm a zzz"); } sdf.toLocalizedPattern(); Date date = launchItem.getNet(); - launchDate = sdf.format(date); + launchTime = sdf.format(date); } else { SimpleDateFormat sdf; if (sharedPref.getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - HH:mm zzz"); + sdf = new SimpleDateFormat("HH:mm zzz"); } else { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + sdf = new SimpleDateFormat("h:mm a zzz"); } Date date = launchItem.getNet(); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); - launchDate = sdf.format(date); + launchTime = sdf.format(date); } } else { - launchDate = "To be determined... "; + launchTime = "To be determined... "; } - holder.launch_date.setText(launchDate); + SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); + sdf.toLocalizedPattern(); + Date date = launchItem.getNet(); + holder.launch_date_compact.setText(sdf.format(date)); + holder.launch_time.setVisibility(View.GONE); + holder.launch_time.setText("NET: " + launchTime); + holder.launch_time.setVisibility(View.VISIBLE); } if (launchItem.getVidURLs() != null) { @@ -469,7 +479,8 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL public TextView location; public TextView content_mission; public TextView content_mission_description; - public TextView launch_date; + public TextView launch_date_compact; + public TextView launch_time; public TextView content_status; public TextView content_TMinus_status; public TextView watchButton; @@ -501,7 +512,8 @@ public ViewHolder(View view) { content_mission = view.findViewById(R.id.content_mission); content_mission_description = view.findViewById( R.id.content_mission_description); - launch_date = view.findViewById(R.id.launch_date); + launch_date_compact = view.findViewById(R.id.launch_date_compact); + launch_time = view.findViewById(R.id.launch_date_full); content_status = view.findViewById(R.id.content_status); content_TMinus_status = view.findViewById(R.id.content_TMinus_status); content_mission_description_view = view.findViewById(R.id.content_mission_description_view); diff --git a/mobile/src/main/res/layout-w500dp/content_card_item.xml b/mobile/src/main/res/layout-w500dp/content_card_item.xml index 5d963c959..a9ee3fa33 100644 --- a/mobile/src/main/res/layout-w500dp/content_card_item.xml +++ b/mobile/src/main/res/layout-w500dp/content_card_item.xml @@ -61,10 +61,11 @@ android:fontFamily="sans-serif-condensed" android:gravity="left" android:maxLines="2" - android:text="Unknown Launch Vehicle" + android:text="Unknown Launch" android:textColor="@color/dark_primary_text_color_selector" - android:textSize="18sp" - android:textStyle="normal" /> + android:textAppearance="@style/MaterialTypography.Tall.Title" + android:textSize="20sp" + android:textStyle="bold" /> + android:textAppearance="@style/MaterialTypography.Regular.Subheading" + android:textColor="@color/dark_primary_text_color_selector" /> + android:textAppearance="@style/MaterialTypography.Regular.Subheading" + android:textColor="@color/dark_primary_text_color_selector" /> @@ -154,6 +157,18 @@ + @@ -62,7 +61,11 @@ android:singleLine="false" android:text="Unknown" android:textAlignment="center" - android:textColor="@color/dark_secondary_text_color_selector" + android:paddingBottom="8dp" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:paddingTop="4dp" + android:textColor="@color/dark_primary_text_color_selector" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> @@ -81,13 +84,14 @@ android:layout_height="wrap_content" android:ellipsize="end" android:gravity="start" - android:lines="1" - android:paddingBottom="@dimen/material_card_supporting_text_padding_bottom" + android:maxLines="2" + android:paddingBottom="@dimen/material_baseline_grid_0.5x" android:paddingLeft="@dimen/material_card_supporting_text_padding_horizontal" android:paddingRight="@dimen/material_card_supporting_text_padding_horizontal" - android:paddingTop="@dimen/material_card_supporting_text_padding_top" + android:layout_marginTop="@dimen/material_baseline_grid_1x" android:text="Agency One" android:textColor="?android:textColorSecondary" + android:textAppearance="@style/MaterialTypography.Regular.Title" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> + android:textAppearance="@style/MaterialTypography.Regular.Caption" /> + android:padding="12dp" /> @@ -184,8 +191,8 @@ android:paddingLeft="@dimen/material_card_supporting_text_padding_horizontal" android:paddingRight="@dimen/material_card_supporting_text_padding_horizontal" android:text="Unknown Agency Type" - android:textColor="?android:textColorSecondary" - android:textSize="@dimen/material_typography_regular_body_1_text_size" /> + android:textAppearance="@style/MaterialTypography.Regular.Caption" + android:textColor="?android:textColorSecondary" /> @@ -292,13 +304,14 @@ android:layout_height="wrap_content" android:ellipsize="end" android:gravity="start" - android:lines="2" - android:paddingBottom="@dimen/material_card_supporting_text_padding_bottom" + android:maxLines="2" + android:paddingBottom="@dimen/material_baseline_grid_0.5x" android:paddingLeft="@dimen/material_card_supporting_text_padding_horizontal" android:paddingRight="@dimen/material_card_supporting_text_padding_horizontal" - android:paddingTop="@dimen/material_card_supporting_text_padding_top" + android:layout_marginTop="@dimen/material_card_supporting_text_padding_top" android:text="Agency One" android:textColor="?android:textColorSecondary" + android:textAppearance="@style/MaterialTypography.Regular.Title" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> + android:textAppearance="@style/MaterialTypography.Regular.Caption" /> + android:textAppearance="@style/MaterialTypography.Regular.Caption" + /> + android:textSize="16sp" /> diff --git a/mobile/src/main/res/layout/content_card_item.xml b/mobile/src/main/res/layout/content_card_item.xml index 1e6d32914..c34a46eef 100644 --- a/mobile/src/main/res/layout/content_card_item.xml +++ b/mobile/src/main/res/layout/content_card_item.xml @@ -60,10 +60,11 @@ android:fontFamily="sans-serif-condensed" android:gravity="left" android:maxLines="2" - android:text="Unknown Launch Vehicle" + android:text="Unknown Launch" android:textColor="@color/dark_primary_text_color_selector" - android:textSize="18sp" - android:textStyle="normal" /> + android:textAppearance="@style/MaterialTypography.Tall.Title" + android:textSize="20sp" + android:textStyle="bold" /> + android:textAppearance="@style/MaterialTypography.Regular.Subheading" + android:textColor="@color/dark_primary_text_color_selector" /> + android:textAppearance="@style/MaterialTypography.Regular.Subheading" + android:textColor="@color/dark_primary_text_color_selector" /> @@ -153,6 +156,19 @@ + + @@ -70,6 +74,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" + android:padding="@dimen/material_baseline_grid_0.5x" android:weightSum="1"> @@ -275,12 +280,15 @@ android:layout_height="wrap_content" android:ellipsize="end" android:gravity="center" - android:paddingBottom="2dp" android:lines="1" android:singleLine="false" android:text="" android:textAlignment="center" - android:textColor="@color/dark_secondary_text_color_selector" + android:paddingBottom="8dp" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:paddingTop="4dp" + android:textColor="@color/dark_primary_text_color_selector" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> diff --git a/mobile/src/main/res/layout/detail_launch_payload.xml b/mobile/src/main/res/layout/detail_launch_payload.xml index 0b161fa15..8eb4dbd51 100644 --- a/mobile/src/main/res/layout/detail_launch_payload.xml +++ b/mobile/src/main/res/layout/detail_launch_payload.xml @@ -51,12 +51,14 @@ android:layout_height="wrap_content" android:ellipsize="end" android:gravity="center" - android:paddingBottom="2dp" + android:paddingBottom="8dp" + android:paddingLeft="8dp" + android:paddingRight="8dp" android:paddingTop="4dp" android:singleLine="false" android:text="Unknown Payload" android:textAlignment="center" - android:textColor="@color/dark_secondary_text_color_selector" + android:textColor="@color/dark_primary_text_color_selector" android:background="?attr/titleBarColor" android:textSize="@dimen/material_typography_regular_subheading_text_size" /> @@ -180,6 +182,7 @@ android:paddingTop="4dp" android:singleLine="false" android:text="Unknown Launch Vehicle" + android:textSize="16sp" android:textAlignment="center" /> From 164d935e234a6d339535c32ea732762bbf95f977 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Thu, 21 Dec 2017 14:44:42 -0500 Subject: [PATCH 15/41] Fix Android Wear 24h-mode. --- .../me/calebjones/spacelaunchnow/wear/SpaceLaunchWatchFace.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wear/src/main/java/me/calebjones/spacelaunchnow/wear/SpaceLaunchWatchFace.java b/wear/src/main/java/me/calebjones/spacelaunchnow/wear/SpaceLaunchWatchFace.java index 9cb44b20c..5869950c5 100644 --- a/wear/src/main/java/me/calebjones/spacelaunchnow/wear/SpaceLaunchWatchFace.java +++ b/wear/src/main/java/me/calebjones/spacelaunchnow/wear/SpaceLaunchWatchFace.java @@ -350,7 +350,7 @@ public void onDraw(Canvas canvas, Rect bounds) { Date now = new Date(); mTime = Calendar.getInstance(); - SimpleDateFormat twentyFourHourMode = new SimpleDateFormat("kk:mm"); + SimpleDateFormat twentyFourHourMode = new SimpleDateFormat("HH:mm"); SimpleDateFormat twelveHourMode = new SimpleDateFormat("h:mm"); if (twentyfourhourmode) { // Draw H:MM in ambient mode or H:MM:SS in interactive mode. From af95b924d95bfbee330c19c090dcfd7d45ed15c7 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Thu, 21 Dec 2017 16:30:58 -0500 Subject: [PATCH 16/41] 2.0.0 - Alpha --- mobile/src/main/res/layout/content_card_item.xml | 2 +- mobile/src/main/res/values/colors.xml | 1 + mobile/version.properties | 4 ++-- wear/version.properties | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/mobile/src/main/res/layout/content_card_item.xml b/mobile/src/main/res/layout/content_card_item.xml index c34a46eef..9354c9e73 100644 --- a/mobile/src/main/res/layout/content_card_item.xml +++ b/mobile/src/main/res/layout/content_card_item.xml @@ -62,7 +62,7 @@ android:maxLines="2" android:text="Unknown Launch" android:textColor="@color/dark_primary_text_color_selector" - android:textAppearance="@style/MaterialTypography.Tall.Title" + android:textAppearance="@style/MaterialTypography.Locale.Title" android:textSize="20sp" android:textStyle="bold" /> diff --git a/mobile/src/main/res/values/colors.xml b/mobile/src/main/res/values/colors.xml index 892dc8468..e1305c23c 100644 --- a/mobile/src/main/res/values/colors.xml +++ b/mobile/src/main/res/values/colors.xml @@ -11,6 +11,7 @@ #2962ff #bbdefb #f44336 + #05A8AA #f44336 #212121 #727272 diff --git a/mobile/version.properties b/mobile/version.properties index f6d7f6f94..e00ca3948 100644 --- a/mobile/version.properties +++ b/mobile/version.properties @@ -1,2 +1,2 @@ -#Thu Dec 21 12:42:59 EST 2017 -AI_VERSION_CODE=5 +#Thu Dec 21 16:02:25 EST 2017 +AI_VERSION_CODE=6 diff --git a/wear/version.properties b/wear/version.properties index f6d7f6f94..e00ca3948 100644 --- a/wear/version.properties +++ b/wear/version.properties @@ -1,2 +1,2 @@ -#Thu Dec 21 12:42:59 EST 2017 -AI_VERSION_CODE=5 +#Thu Dec 21 16:02:25 EST 2017 +AI_VERSION_CODE=6 From 9cc83e41eca06e2b5572b96482d6a18aa1c0ba16 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Tue, 26 Dec 2017 14:05:19 -0500 Subject: [PATCH 17/41] Testing --- mobile/src/main/res/values-v21/styles.xml | 2 +- mobile/src/main/res/values/colors.xml | 2 ++ mobile/src/main/res/values/styles.xml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mobile/src/main/res/values-v21/styles.xml b/mobile/src/main/res/values-v21/styles.xml index f6539be59..ef6b54dab 100644 --- a/mobile/src/main/res/values-v21/styles.xml +++ b/mobile/src/main/res/values-v21/styles.xml @@ -4,7 +4,7 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent - @color/colorAccent + @color/colorStatusGo @android:color/white @color/materialGrey #212121 diff --git a/mobile/src/main/res/values/colors.xml b/mobile/src/main/res/values/colors.xml index e1305c23c..dc50fac23 100644 --- a/mobile/src/main/res/values/colors.xml +++ b/mobile/src/main/res/values/colors.xml @@ -15,6 +15,8 @@ #f44336 #212121 #727272 + #4CAF50 + #d32f2f #607D8B #81c784 diff --git a/mobile/src/main/res/values/styles.xml b/mobile/src/main/res/values/styles.xml index 81a1e7dae..4f26d99f1 100644 --- a/mobile/src/main/res/values/styles.xml +++ b/mobile/src/main/res/values/styles.xml @@ -34,7 +34,7 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent - @color/colorAccent + @color/colorPrimary #212121 #757575 From e97a107235a560d0bdf5d81f79f0234344a30844 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Tue, 26 Dec 2017 14:34:56 -0500 Subject: [PATCH 18/41] Fix migration --- .../java/me/calebjones/spacelaunchnow/LaunchApplication.java | 2 +- mobile/version.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/LaunchApplication.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/LaunchApplication.java index ade6587f8..0a780b935 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/LaunchApplication.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/LaunchApplication.java @@ -158,7 +158,7 @@ public void onCreate() { Realm.init(this); RealmConfiguration config = new RealmConfiguration.Builder() - .schemaVersion(Constants.DB_SCHEMA_VERSION_1_8_1) + .schemaVersion(Constants.DB_SCHEMA_VERSION_2_0_0) .modules(Realm.getDefaultModule(), new LaunchDataModule()) .migration(new Migration()) .build(); diff --git a/mobile/version.properties b/mobile/version.properties index e00ca3948..c24784b2d 100644 --- a/mobile/version.properties +++ b/mobile/version.properties @@ -1,2 +1,2 @@ -#Thu Dec 21 16:02:25 EST 2017 -AI_VERSION_CODE=6 +#Thu Dec 21 12:31:31 EST 2017 +AI_VERSION_CODE=1020 From 69318151d8749c3f68888e0c16e5349e22ba902c Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Tue, 26 Dec 2017 14:48:29 -0500 Subject: [PATCH 19/41] Fix migration maybe --- .../data/models/realm/Migration.java | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java index fd6cde134..7662e9ccd 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/realm/Migration.java @@ -73,33 +73,35 @@ public void apply(DynamicRealmObject obj) { } if (oldVersion <= Constants.DB_SCHEMA_VERSION_1_8_1) { - schema.remove("RocketDetails"); - RealmObjectSchema details = schema.create("RocketDetail"); + if (schema.get("RocketDetails") != null){ + schema.remove("RocketDetails"); + RealmObjectSchema details = schema.create("RocketDetail"); - if (details != null){ - Timber.i("Migrating RocketDetail to new schema."); - details.addField("id", int.class, FieldAttribute.PRIMARY_KEY) - .addField("name", String.class) - .addField("infoURL", String.class) - .addField("wikiURL", String.class) - .addField("imageURL", String.class) - .addField("description", String.class) - .addField("alias", String.class) - .addField("variant", String.class) - .addField("family", String.class) - .addField("sFamily", String.class) - .addField("manufacturer", String.class) - .addField("length", String.class) - .addField("diameter", String.class) - .addField("launchMass", String.class) - .addField("leoCapacity", String.class) - .addField("gtoCapacity", String.class) - .addField("thrust", String.class) - .addField("vehicleClass", String.class) - .addField("apogee", String.class) - .addField("range", String.class) - .addField("maxStage", Integer.class) - .addField("minStage", Integer.class); + if (details != null){ + Timber.i("Migrating RocketDetail to new schema."); + details.addField("id", int.class, FieldAttribute.PRIMARY_KEY) + .addField("name", String.class) + .addField("infoURL", String.class) + .addField("wikiURL", String.class) + .addField("imageURL", String.class) + .addField("description", String.class) + .addField("alias", String.class) + .addField("variant", String.class) + .addField("family", String.class) + .addField("sFamily", String.class) + .addField("manufacturer", String.class) + .addField("length", String.class) + .addField("diameter", String.class) + .addField("launchMass", String.class) + .addField("leoCapacity", String.class) + .addField("gtoCapacity", String.class) + .addField("thrust", String.class) + .addField("vehicleClass", String.class) + .addField("apogee", String.class) + .addField("range", String.class) + .addField("maxStage", Integer.class) + .addField("minStage", Integer.class); + } } oldVersion++; } From 98705b52de678f29fb88d2de206ecfc2129efb29 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Tue, 26 Dec 2017 15:34:39 -0500 Subject: [PATCH 20/41] Launch Details fixup --- .../activity/LaunchDetailActivity.java | 3 - .../{CardBigAdapter.java => CardAdapter.java} | 8 +- .../ui/main/next/NextLaunchFragment.java | 5 +- .../res/layout/activity_launch_detail.xml | 278 ++++++++---------- mobile/src/main/res/values-v21/styles.xml | 2 +- mobile/src/main/res/values/colors.xml | 2 +- 6 files changed, 139 insertions(+), 159 deletions(-) rename mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/{CardBigAdapter.java => CardAdapter.java} (98%) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java index 9a8b7efb2..b0a97f310 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java @@ -79,8 +79,6 @@ public class LaunchDetailActivity extends BaseActivity ViewPager viewPager; @BindView(R.id.rootview) CoordinatorLayout rootview; - @BindView(R.id.content) - FrameLayout content; @BindView(R.id.detail_swipe_refresh) SwipeRefreshLayout detailSwipeRefresh; @BindView(R.id.detail_tabs) @@ -394,7 +392,6 @@ private void getLaunchVehicle(Launch result, boolean setImage) { if (launchVehicle != null && launchVehicle.getImageURL().length() > 0 && !launchVehicle.getImageURL().contains("placeholder")) { GlideApp.with(this) .load(launchVehicle.getImageURL()) - .placeholder(R.drawable.placeholder) .into(detail_profile_backdrop); Timber.d("Glide Loading: %s %s", launchVehicle.getName(), launchVehicle.getImageURL()); } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java similarity index 98% rename from mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java rename to mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java index ae30081df..1fbfdea43 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardBigAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java @@ -48,7 +48,7 @@ /** * Adapts UpcomingLaunch data to the LaunchFragment */ -public class CardBigAdapter extends RecyclerView.Adapter implements SectionIndexer { +public class CardAdapter extends RecyclerView.Adapter implements SectionIndexer { private static ListPreferences sharedPreference; public int position; @@ -63,7 +63,7 @@ public class CardBigAdapter extends RecyclerView.Adapter(); this.context = context; @@ -191,18 +191,22 @@ public boolean onPreDraw() { case 1: //GO for launch holder.content_status.setText(R.string.status_go); +// holder.content_status.setBackgroundColor(ContextCompat.getColor(context, R.color.colorStatusGo)); break; case 2: //NO GO for launch holder.content_status.setText(R.string.status_nogo); +// holder.content_status.setBackgroundColor(ContextCompat.getColor(context, R.color.colorStatusNoGo)); break; case 3: //Success for launch holder.content_status.setText(R.string.status_success); +// holder.content_status.setBackgroundColor(ContextCompat.getColor(context, R.color.colorStatusGo)); break; case 4: //Failure to launch holder.content_status.setText(R.string.status_failure); +// holder.content_status.setBackgroundColor(ContextCompat.getColor(context, R.color.colorStatusNoGo)); break; } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java index 60f03aafc..83ad09741 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java @@ -51,7 +51,6 @@ import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.jobs.UpdateWearJob; import me.calebjones.spacelaunchnow.content.services.LibraryDataManager; -import me.calebjones.spacelaunchnow.content.services.NextLaunchTracker; import me.calebjones.spacelaunchnow.content.util.QueryBuilder; import me.calebjones.spacelaunchnow.data.models.Constants; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; @@ -99,7 +98,7 @@ public class NextLaunchFragment extends BaseFragment implements SwipeRefreshLayo private View view; private RecyclerView mRecyclerView; - private CardBigAdapter adapter; + private CardAdapter adapter; private StaggeredGridLayoutManager layoutManager; private LinearLayoutManager linearLayoutManager; private SwipeRefreshLayout mSwipeRefreshLayout; @@ -137,7 +136,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, sharedPref = PreferenceManager.getDefaultSharedPreferences(context); if (adapter == null) { - adapter = new CardBigAdapter(getActivity()); + adapter = new CardAdapter(getActivity()); } diff --git a/mobile/src/main/res/layout/activity_launch_detail.xml b/mobile/src/main/res/layout/activity_launch_detail.xml index 529b07c69..895f31d53 100644 --- a/mobile/src/main/res/layout/activity_launch_detail.xml +++ b/mobile/src/main/res/layout/activity_launch_detail.xml @@ -1,163 +1,143 @@ + android:layout_height="match_parent"> - + android:layout_height="wrap_content" + android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> - + android:layout_height="224dp" + + app:contentScrim="?attr/colorPrimary" + app:expandedTitleMarginEnd="64dp" + app:expandedTitleMarginStart="48dp" + app:layout_scrollFlags="scroll|snap"> - - - - - - - - - - - - - - - ​ - - - ​ - - - ​ - - - ​ - - - ​ - - ​ - - - - - - - - - ​ - - - - - - - + + + + + + ​ + + + ​ + + + ​ + + + ​ + + + android:layout_gravity="center_horizontal" + android:layout_margin="4dp" + android:maxLines="1" + android:text="Unknown Mission and Location" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle" + android:textColor="@android:color/white" /> + ​ + + ​ + + + + + + + + - - \ No newline at end of file + + + + ​ + + + diff --git a/mobile/src/main/res/values-v21/styles.xml b/mobile/src/main/res/values-v21/styles.xml index ef6b54dab..bbde9b79e 100644 --- a/mobile/src/main/res/values-v21/styles.xml +++ b/mobile/src/main/res/values-v21/styles.xml @@ -4,7 +4,7 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent - @color/colorStatusGo + @color/colorPrimary @android:color/white @color/materialGrey #212121 diff --git a/mobile/src/main/res/values/colors.xml b/mobile/src/main/res/values/colors.xml index dc50fac23..861984e62 100644 --- a/mobile/src/main/res/values/colors.xml +++ b/mobile/src/main/res/values/colors.xml @@ -9,7 +9,7 @@ #448AFF #1565c0 #2962ff - #bbdefb + #42a5f5 #f44336 #05A8AA #f44336 From b6ee293d248795f17d930832eb5770304151d54f Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Tue, 26 Dec 2017 22:19:05 -0500 Subject: [PATCH 21/41] Fix Details --- .../activity/LaunchDetailActivity.java | 6 ++- .../res/layout/activity_launch_detail.xml | 39 +++++++++---------- .../res/layout/activity_orbiter_detail.xml | 3 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java index b0a97f310..0a7d7e880 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java @@ -18,7 +18,6 @@ import android.view.View; import android.view.Window; import android.view.WindowManager; -import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; @@ -55,6 +54,7 @@ import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.customtab.CustomTabActivityHelper; +import me.calebjones.spacelaunchnow.utils.views.CustomOnOffsetChangedListener; import me.calebjones.spacelaunchnow.utils.views.SnackbarHandler; import retrofit2.Call; import retrofit2.Callback; @@ -239,7 +239,7 @@ public void onClick(View v) { } ); - + appBarLayout.addOnOffsetChangedListener(new CustomOnOffsetChangedListener(statusColor, getWindow())); appBarLayout.addOnOffsetChangedListener(this); mMaxScrollSize = appBarLayout.getTotalScrollRange(); @@ -440,6 +440,8 @@ public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { .start(); fabShare.show(); + + } } diff --git a/mobile/src/main/res/layout/activity_launch_detail.xml b/mobile/src/main/res/layout/activity_launch_detail.xml index 895f31d53..ee6974e4b 100644 --- a/mobile/src/main/res/layout/activity_launch_detail.xml +++ b/mobile/src/main/res/layout/activity_launch_detail.xml @@ -3,28 +3,29 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/rootview" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:fitsSystemWindows="true"> + android:fitsSystemWindows="true"> + app:layout_scrollFlags="scroll"> @@ -38,12 +39,10 @@ android:layout_gravity="center_horizontal" android:layout_marginTop="-48dp" android:elevation="8dp" - app:civ_border_color="#FFF" app:civ_border_width="4dp" app:layout_scrollFlags="scroll" app:srcCompat="@drawable/icon_international" /> - ​ - ​ - ​ + android:orientation="vertical" + android:paddingBottom="8dp"> + android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" + android:textColor="@android:color/white" /> ​ - + @@ -127,7 +126,7 @@ android:layout_gravity="center|bottom" android:visibility="gone" ads:adSize="SMART_BANNER" - ads:adUnitId="ca-app-pub-9824528399164059/9713798255"/> + ads:adUnitId="ca-app-pub-9824528399164059/9713798255" /> - Date: Sun, 31 Dec 2017 02:16:03 -0500 Subject: [PATCH 22/41] 2.0.0 Alpha --- .gitignore | 1 + .../spacelaunchnow/data/models/Constants.java | 1 + mobile/build.gradle | 31 ++- mobile/src/main/AndroidManifest.xml | 17 ++ .../spacelaunchnow/LaunchApplication.java | 1 - .../spacelaunchnow/common/BaseActivity.java | 23 ++ .../content/jobs/DataJobCreator.java | 4 + .../content/services/NextLaunchTracker.java | 12 + .../content/util/QueryBuilder.java | 4 +- .../spacelaunchnow/ui/main/MainActivity.java | 101 ++++++-- .../ui/main/next/NextLaunchFragment.java | 15 ++ .../ui/settings/AboutActivity.java | 39 ++++ .../ui/settings/DebugAuthManager.java | 2 +- .../fragments/AppearanceFragment.java | 24 +- .../ui/supporter/SupporterActivity.java | 123 ++++++++-- .../utils/UniqueIdentifier.java | 10 + .../spacelaunchnow/utils/Utils.java | 92 +++++++- .../widget/WidgetJobService.java | 11 + .../launchcard/LaunchCardCompactManager.java | 75 +++--- .../widget/launchlist/LaunchListFactory.java | 215 ++++++++++++++++++ .../widget/launchlist/LaunchListManager.java | 167 ++++++++++++++ .../launchlist/LaunchListWidgetProvider.java | 60 +++++ .../launchlist/LaunchListWidgetService.java | 15 ++ .../launchlist/UpdateLaunchListJob.java | 40 ++++ .../wordtimer/LaunchWordTimerManager.java | 29 +-- mobile/src/main/res/drawable/ic_money.xml | 9 + .../drawable/launch_card_compact_preview.png | Bin 12936 -> 0 bytes .../res/drawable/launch_card_preview.webp | Bin 0 -> 41980 bytes .../res/drawable/launch_list_preview.webp | Bin 0 -> 86986 bytes .../res/drawable/launch_timer_preview.webp | Bin 0 -> 18348 bytes mobile/src/main/res/drawable/rounded_top.xml | 6 + .../main/res/drawable/word_timer_preview.png | Bin 13046 -> 0 bytes .../res/layout/activity_launch_detail.xml | 37 +-- .../src/main/res/layout/activity_support.xml | 31 ++- .../src/main/res/layout/launch_list_item.xml | 10 +- .../res/layout/small_content_card_item.xml | 181 --------------- .../main/res/layout/view_custom_button.xml | 14 -- mobile/src/main/res/layout/whats_new.xml | 12 - .../src/main/res/layout/whats_new_night.xml | 13 -- .../res/layout/widget_become_supporter.xml | 62 +++++ .../res/layout/widget_config_activity.xml | 105 --------- .../main/res/layout/widget_launch_card.xml | 6 - .../widget_launch_card_compact_dark.xml | 42 ++-- .../widget_launch_card_compact_large_dark.xml | 36 ++- .../widget_launch_card_compact_small_dark.xml | 41 ++-- .../main/res/layout/widget_launch_list.xml | 56 +++++ .../res/layout/widget_launch_timer_dark.xml | 76 ------- .../layout/widget_launch_timer_large_dark.xml | 76 ------- .../layout/widget_launch_timer_small_dark.xml | 78 ------- mobile/src/main/res/menu/menu_support.xml | 10 +- mobile/src/main/res/values-night/themes.xml | 9 + mobile/src/main/res/values/arrays.xml | 22 ++ mobile/src/main/res/values/attrs.xml | 1 + mobile/src/main/res/values/colors.xml | 15 +- mobile/src/main/res/values/ids.xml | 2 + mobile/src/main/res/values/styles.xml | 8 +- .../widget_launch_card_compact_info.xml | 4 +- .../xml-v17/widget_launch_word_timer_info.xml | 4 +- .../main/res/xml/appearance_preferences.xml | 18 ++ .../xml/widget_launch_card_compact_info.xml | 4 +- .../widget_launch_list_info.xml} | 10 +- .../main/res/xml/widget_launch_timer_info.xml | 13 -- .../res/xml/widget_launch_word_timer_info.xml | 4 +- mobile/version.properties | 4 +- wear/version.properties | 4 +- 65 files changed, 1356 insertions(+), 779 deletions(-) create mode 100644 mobile/src/main/java/me/calebjones/spacelaunchnow/utils/UniqueIdentifier.java create mode 100644 mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java create mode 100644 mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java create mode 100644 mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListWidgetProvider.java create mode 100644 mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListWidgetService.java create mode 100644 mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/UpdateLaunchListJob.java create mode 100644 mobile/src/main/res/drawable/ic_money.xml delete mode 100755 mobile/src/main/res/drawable/launch_card_compact_preview.png create mode 100644 mobile/src/main/res/drawable/launch_card_preview.webp create mode 100644 mobile/src/main/res/drawable/launch_list_preview.webp create mode 100644 mobile/src/main/res/drawable/launch_timer_preview.webp create mode 100644 mobile/src/main/res/drawable/rounded_top.xml delete mode 100755 mobile/src/main/res/drawable/word_timer_preview.png delete mode 100644 mobile/src/main/res/layout/small_content_card_item.xml delete mode 100644 mobile/src/main/res/layout/view_custom_button.xml delete mode 100644 mobile/src/main/res/layout/whats_new.xml delete mode 100644 mobile/src/main/res/layout/whats_new_night.xml create mode 100644 mobile/src/main/res/layout/widget_become_supporter.xml delete mode 100644 mobile/src/main/res/layout/widget_config_activity.xml delete mode 100644 mobile/src/main/res/layout/widget_launch_card.xml create mode 100644 mobile/src/main/res/layout/widget_launch_list.xml delete mode 100644 mobile/src/main/res/layout/widget_launch_timer_dark.xml delete mode 100644 mobile/src/main/res/layout/widget_launch_timer_large_dark.xml delete mode 100644 mobile/src/main/res/layout/widget_launch_timer_small_dark.xml rename mobile/src/main/res/{xml-v17/widget_launch_timer_info.xml => xml/widget_launch_list_info.xml} (53%) delete mode 100644 mobile/src/main/res/xml/widget_launch_timer_info.xml diff --git a/.gitignore b/.gitignore index 1357fbdba..3a6c0ad80 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ projectFilesBackup/.idea/workspace.xml *.apk +keystore.properties diff --git a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java index 6de2fcef1..4f19281ea 100644 --- a/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java +++ b/data/src/main/java/me/calebjones/spacelaunchnow/data/models/Constants.java @@ -24,6 +24,7 @@ public final class Constants { public static final String ACTION_GET_UP_LAUNCHES_MINI = "GET_UP_LAUNCHES_MINI"; public static final String ACTION_UPDATE_LAUNCH_CARD = "UPDATE_LAUNCH_CARD"; public static final String ACTION_UPDATE_WORD_TIMER = "UPDATE_WORD_TIMER"; + public static final String ACTION_UPDATE_LAUNCH_LIST = "UPDATE_LAUNCH_LIST"; public static int NOTIF_ID = 568975; public static int NOTIF_ID_DAY = 568985; public static int NOTIF_ID_HOUR = 568995; diff --git a/mobile/build.gradle b/mobile/build.gradle index 168f5ca34..54fe83652 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -46,7 +46,30 @@ repositories { google() } +// Create a variable called keystorePropertiesFile, and initialize it to your +// keystore.properties file, in the rootProject folder. +def keystorePropertiesFile = rootProject.file("keystore.properties") + +// Initialize a new Properties() object called keystoreProperties. +def keystoreProperties = new Properties() + +if (keystorePropertiesFile.canRead()) { +// Load your keystore.properties file into the keystoreProperties object. + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} else { + throw new GradleException("Could not read keystore.properties!") +} + android { + signingConfigs { + releaseConfig { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile file(keystoreProperties['storeFile']) + storePassword keystoreProperties['storePassword'] + } + } + def appVersionCode = app.versionMajor * 10000 + app.versionMinor * 1000 + app.versionPatch * 100 + advancedVersioning.versionCode flavorDimensions "release" compileSdkVersion 27 @@ -94,6 +117,7 @@ android { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.releaseConfig } validation.initWith(debug) @@ -184,7 +208,10 @@ dependencies { } implementation 'com.jakewharton.timber:timber:4.6.0' implementation 'com.karumi:dexter:4.2.0' + + // Billing implementation 'com.anjlab.android.iab.v3:library:1.0.44' + implementation 'com.evernote:android-job:1.2.1' implementation 'blue.aodev:material-values:1.1.1' @@ -208,9 +235,10 @@ dependencies { implementation 'net.mediavrog:integrated-rating-request:1.1.2' implementation 'com.simplecityapps:recyclerview-fastscroll:1.0.16' implementation 'jp.wasabeef:glide-transformations:3.0.1' + // If you want to use the GPU Filters implementation 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.4.1' - implementation("com.mikepenz:materialdrawer:6.0.2@aar") { + implementation('com.mikepenz:materialdrawer:6.0.2@aar') { transitive = true } @@ -220,7 +248,6 @@ dependencies { implementation 'com.github.renaudcerrato:static-maps-api:1.0.4' implementation 'com.google.code.gson:gson:2.8.2' implementation 'com.squareup.okhttp3:okhttp:3.9.1' - implementation 'android.zetterstrom.com.forecast:forecast:1.2.0' implementation 'it.macisamuele:calendarprovider-lib:0.0.1' diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml index 39d7a8334..5a33eac16 100644 --- a/mobile/src/main/AndroidManifest.xml +++ b/mobile/src/main/AndroidManifest.xml @@ -130,6 +130,7 @@ android:name="android.appwidget.provider" android:resource="@xml/widget_launch_card_compact_info" /> + @@ -144,6 +145,22 @@ android:resource="@xml/widget_launch_word_timer_info" /> + + + + + + + + + + + = Build.VERSION_CODES.LOLLIPOP) { + + TypedValue typedValue = new TypedValue(); + Resources.Theme theme = getTheme(); + theme.resolveAttribute(R.attr.recentBarColor, typedValue, true); + int color = typedValue.data; + + Bitmap bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round); + ActivityManager.TaskDescription td = new ActivityManager.TaskDescription(null, bm, color); + + setTaskDescription(td); + if (bm != null) { + bm.recycle(); + } + } } @Override diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/jobs/DataJobCreator.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/jobs/DataJobCreator.java index 8a9aa56e6..7220c0f3a 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/jobs/DataJobCreator.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/jobs/DataJobCreator.java @@ -4,6 +4,7 @@ import com.evernote.android.job.JobCreator; import me.calebjones.spacelaunchnow.widget.launchcard.UpdateLaunchCardJob; +import me.calebjones.spacelaunchnow.widget.launchlist.UpdateLaunchListJob; import me.calebjones.spacelaunchnow.widget.wordtimer.UpdateWordTimerJob; import timber.log.Timber; @@ -36,6 +37,9 @@ public Job create(String tag) { case LibraryDataJob.TAG: Timber.v(LibraryDataJob.TAG); return new LibraryDataJob(); + case UpdateLaunchListJob.TAG: + Timber.v(UpdateLaunchListJob.TAG); + return new UpdateLaunchListJob(); default: return null; } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/NextLaunchTracker.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/NextLaunchTracker.java index 4119897a3..3d1e81748 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/NextLaunchTracker.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/services/NextLaunchTracker.java @@ -8,6 +8,8 @@ import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.jobs.SyncJob; import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactManager; +import me.calebjones.spacelaunchnow.widget.launchlist.LaunchListManager; +import me.calebjones.spacelaunchnow.widget.launchlist.LaunchListWidgetProvider; import me.calebjones.spacelaunchnow.widget.wordtimer.LaunchWordTimerManager; import me.calebjones.spacelaunchnow.content.wear.WearWatchfaceManager; import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactWidgetProvider; @@ -40,6 +42,8 @@ public void runUpdate() { public void updateWidgets() { LaunchCardCompactManager launchCardCompactManager = new LaunchCardCompactManager(context); LaunchWordTimerManager launchWordTimerManager = new LaunchWordTimerManager(context); + LaunchListManager launchListManager = new LaunchListManager(context); + int cardIds[] = AppWidgetManager.getInstance(context) .getAppWidgetIds(new ComponentName(context, LaunchCardCompactWidgetProvider.class)); @@ -55,6 +59,14 @@ public void updateWidgets() { for (int id : timerIds){ launchWordTimerManager.updateAppWidget(id); } + + int listIds[] = AppWidgetManager.getInstance(context) + .getAppWidgetIds(new ComponentName(context, + LaunchListWidgetProvider.class)); + + for (int id : listIds){ + launchListManager.updateAppWidget(id); + } } public void syncCalendar() { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java index 3e8dcadc8..19d8ed4f4 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/util/QueryBuilder.java @@ -641,7 +641,9 @@ public static RealmResults buildSwitchQuery(Context context, Realm realm query.equalTo("location.id", 18); } - return query.endGroup().findAllSorted("net", Sort.ASCENDING); + query.endGroup(); + + return query.findAllSorted("net", Sort.ASCENDING); } public static RealmResults buildSwitchQuery(Context context, Realm realm, boolean calendarState) { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java index e97fd26c0..258fa9440 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java @@ -21,6 +21,7 @@ import android.widget.RelativeLayout; import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.GravityEnum; import com.afollestad.materialdialogs.MaterialDialog; import com.crashlytics.android.Crashlytics; import com.google.android.gms.ads.AdListener; @@ -35,6 +36,7 @@ import com.mikepenz.materialdrawer.DrawerBuilder; import com.mikepenz.materialdrawer.holder.ImageHolder; import com.mikepenz.materialdrawer.model.DividerDrawerItem; +import com.mikepenz.materialdrawer.model.ExpandableDrawerItem; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.SecondaryDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; @@ -228,6 +230,37 @@ public void onAdLoaded() { .withIdentifier(R.id.menu_settings) .withSelectable(true), new DividerDrawerItem(), + new ExpandableDrawerItem().withName("Stay Connected").withIcon(CommunityMaterial.Icon.cmd_account).withDescription("Connect with the Community").withIdentifier(19).withSelectable(false).withSubItems( + new SecondaryDrawerItem() + .withIcon(CommunityMaterial.Icon.cmd_discord) + .withLevel(2) + .withName("Discord") + .withDescription("Hop on Discord during launches!") + .withIdentifier(R.id.menu_discord) + .withSelectable(false), + new SecondaryDrawerItem() + .withIcon(CommunityMaterial.Icon.cmd_twitter) + .withLevel(2) + .withName("Twitter") + .withDescription("Connect on Twitter!") + .withIdentifier(R.id.menu_twitter) + .withSelectable(false), + new SecondaryDrawerItem() + .withIcon(CommunityMaterial.Icon.cmd_facebook) + .withLevel(2) + .withName("Facebook") + .withDescription("Follow on Facebook") + .withIdentifier(R.id.menu_facebook) + .withSelectable(false), + new SecondaryDrawerItem() + .withIcon(CommunityMaterial.Icon.cmd_web) + .withLevel(2) + .withName("On the Web") + .withDescription("Bookmark spacelaunchnow.me") + .withIdentifier(R.id.menu_website) + .withSelectable(false) + ), + new DividerDrawerItem(), new SecondaryDrawerItem() .withIcon(GoogleMaterial.Icon.gmd_info_outline) .withName("What's New?") @@ -239,18 +272,6 @@ public void onAdLoaded() { .withName("Feedback") .withDescription("Found a bug?") .withIdentifier(R.id.menu_feedback) - .withSelectable(false), - new SecondaryDrawerItem() - .withIcon(CommunityMaterial.Icon.cmd_twitter) - .withName("Twitter") - .withDescription("Stay connected on Twitter!") - .withIdentifier(R.id.menu_twitter) - .withSelectable(false), - new SecondaryDrawerItem() - .withIcon(CommunityMaterial.Icon.cmd_discord) - .withName("Discord") - .withDescription("Join us on Discord during launches!") - .withIdentifier(R.id.menu_discord) .withSelectable(false) ).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { @Override @@ -476,6 +497,19 @@ private void navigate(final int itemId) { Intent discordIntent = new Intent(Intent.ACTION_VIEW); discordIntent.setData(Uri.parse(discordUrl)); startActivity(discordIntent); + break; + case R.id.menu_facebook: + String facebookUrl = "https://www.facebook.com/spacelaunchnow/"; + Intent facebookIntent = new Intent(Intent.ACTION_VIEW); + facebookIntent.setData(Uri.parse(facebookUrl)); + startActivity(facebookIntent); + break; + case R.id.menu_website: + String websiteUrl = "https://spacelaunchnow.me/"; + Intent websiteIntent = new Intent(Intent.ACTION_VIEW); + websiteIntent.setData(Uri.parse(websiteUrl)); + startActivity(websiteIntent); + break; default: // ignore break; @@ -487,7 +521,7 @@ private void showFeedback() { .title("Submit Feedback") .autoDismiss(true) .content("Feel free to submit bugs or feature requests for anything related to the app. If you found an issue with the launch data, the libraries at Launch Library that provide the data can be contacted via Discord or Reddit.") - .positiveColor(ContextCompat.getColor(this, R.color.colorAccent)) + .neutralColor(ContextCompat.getColor(this, R.color.colorPrimary)) .negativeText("Launch Data") .onNegative(new MaterialDialog.SingleButtonCallback() { @Override @@ -503,10 +537,39 @@ public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) .onPositive(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { - String url = "https://discord.gg/WVfzEDW"; - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - startActivity(i); + dialog.getBuilder() + .title("Need Support?") + .content("The fastest and most reliable way to get support is through Discord. If thats not an option feel free to email me directly.") + .neutralText("Email") + .negativeText("Cancel") + .positiveText("Discord") + .onNeutral(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(MaterialDialog dialog, DialogAction which) { + Intent intent = new Intent(Intent.ACTION_SENDTO); + intent.setData(Uri.parse("mailto:")); + intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"support@calebjones.me"}); + intent.putExtra(Intent.EXTRA_SUBJECT, "Space Launch Now - Feedback"); + + startActivity(Intent.createChooser(intent, "Email via...")); + } + }) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(MaterialDialog dialog, DialogAction which) { + String url = "https://discord.gg/WVfzEDW"; + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + startActivity(i); + } + }) + .onNegative(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + dialog.dismiss(); + } + }) + .show(); } }) .show(); @@ -530,8 +593,8 @@ private void showAd() { @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(FilterViewEvent event) { - if (!SupporterHelper.isSupporter()){ - if (event.isOpened){ + if (!SupporterHelper.isSupporter()) { + if (event.isOpened) { hideAd(); } else { showAd(); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java index 83ad09741..9cead47ca 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/NextLaunchFragment.java @@ -61,6 +61,8 @@ import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactManager; import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactWidgetProvider; +import me.calebjones.spacelaunchnow.widget.launchlist.LaunchListManager; +import me.calebjones.spacelaunchnow.widget.launchlist.LaunchListWidgetProvider; import me.calebjones.spacelaunchnow.widget.wordtimer.LaunchWordTimerManager; import me.calebjones.spacelaunchnow.widget.wordtimer.LaunchWordTimerWidgetProvider; import timber.log.Timber; @@ -548,6 +550,8 @@ private void checkFilter() { if (switchChanged) { LaunchCardCompactManager launchCardCompactManager = new LaunchCardCompactManager(context); LaunchWordTimerManager launchWordTimerManager = new LaunchWordTimerManager(context); + LaunchListManager launchListManager = new LaunchListManager(context); + int cardIds[] = AppWidgetManager.getInstance(context) .getAppWidgetIds(new ComponentName(context, LaunchCardCompactWidgetProvider.class)); @@ -563,6 +567,15 @@ private void checkFilter() { for (int id : timerIds){ launchWordTimerManager.updateAppWidget(id); } + + int listIds[] = AppWidgetManager.getInstance(context) + .getAppWidgetIds(new ComponentName(context, + LaunchListWidgetProvider.class)); + + for (int id : listIds){ + launchListManager.updateAppWidget(id); + } + UpdateWearJob.scheduleJobNow(); displayLaunches(); if (switchPreferences.getCalendarStatus()) { @@ -678,6 +691,7 @@ public void all_switch() { @OnClick(R.id.no_go_launch) public void noGoSwitch() { + confirm(); switchPreferences.setNoGoSwitch(noGoSwitch.isChecked()); displayLaunches(); @@ -686,6 +700,7 @@ public void noGoSwitch() { @OnClick(R.id.persist_last_launch) public void setPersistLastSwitch() { + confirm(); switchPreferences.setPersistLastSwitch(persistLastSwitch.isChecked()); displayLaunches(); } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java index e140737aa..55f6e968c 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java @@ -1,18 +1,25 @@ package me.calebjones.spacelaunchnow.ui.settings; +import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.SupportActivity; import android.support.v7.app.AppCompatActivity; +import android.text.InputType; +import android.view.View; import android.widget.FrameLayout; +import android.widget.Toast; + import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.ui.changelog.ChangelogActivity; +import me.calebjones.spacelaunchnow.ui.debug.DebugActivity; import me.calebjones.spacelaunchnow.ui.intro.OnboardingActivity; import me.calebjones.spacelaunchnow.ui.supporter.SupporterActivity; import me.calebjones.spacelaunchnow.utils.Utils; +import com.afollestad.materialdialogs.MaterialDialog; import com.mikepenz.community_material_typeface_library.CommunityMaterial; import com.mikepenz.iconics.Iconics; import com.mikepenz.iconics.IconicsDrawable; @@ -20,10 +27,13 @@ import com.vansuita.materialabout.views.AboutView; public class AboutActivity extends AppCompatActivity { + + private Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + this.context = this; setContentView(R.layout.activity_about); loadAbout(); } @@ -64,6 +74,30 @@ private void loadAbout() { .sizeDp(24).toBitmap(), "Discord", "https://discord.gg/WVfzEDW") + .addAction(new IconicsDrawable(this) + .icon(CommunityMaterial.Icon.cmd_android_debug_bridge) + .sizeDp(24).toBitmap(), + "Debug", new View.OnClickListener() { + @Override + public void onClick(View view) { + new MaterialDialog.Builder(context) + .title("Enter Support Code") + .content("To debug the application - please enter the code from support.") + .inputType(InputType.TYPE_CLASS_NUMBER) + .input("Support Code", null, new MaterialDialog.InputCallback() { + @Override + public void onInput(MaterialDialog dialog, CharSequence input) { + // Do something + if(DebugAuthManager.getAuthResult(input)){ + goToDebug(); + } else { + Toast.makeText(context, "Error - Support code was not correct.", Toast.LENGTH_LONG).show(); + } + } + }).show(); + } + } + ) .setWrapScrollView(true) .setShowAsCard(true); @@ -72,4 +106,9 @@ private void loadAbout() { flHolder.addView(view); } + + private void goToDebug() { + Intent i = new Intent(AboutActivity.this, DebugActivity.class); + startActivity(i); + } } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/DebugAuthManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/DebugAuthManager.java index f2c6ecaec..f3042ed09 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/DebugAuthManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/DebugAuthManager.java @@ -9,7 +9,7 @@ public class DebugAuthManager { public static boolean getAuthResult(CharSequence input){ Date date = Calendar.getInstance().getTime(); - DateFormat formatter = new SimpleDateFormat("ddMMyyyy"); + DateFormat formatter = new SimpleDateFormat("MMddyyyy"); String today = formatter.format(date); int factor = Calendar.getInstance().get(Calendar.DAY_OF_MONTH); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java index 66d43e30a..4cdd760d6 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java @@ -37,11 +37,15 @@ public class AppearanceFragment extends BaseSettingFragment implements SharedPre private ColorPreference widgetTextColor; private ColorPreference widgetSecondaryTextColor; private ColorPreference widgetIconColor; + private ColorPreference widgetAccentColor; + private ColorPreference widgetTitleColor; private SwitchPreference widgetRoundCorners; private boolean isCustomColor = false; private int[] textPrimaryArray; private int[] textSecondaryArray; private int[] backgroundArray; + private int[] accentArray; + private int[] titleTextArray; @Override public void onCreate(Bundle savedInstanceState) { @@ -52,6 +56,8 @@ public void onCreate(Bundle savedInstanceState) { textPrimaryArray = getResources().getIntArray(R.array.widget_presets_values_text_primary); textSecondaryArray = getResources().getIntArray(R.array.widget_presets_values_text_secondary); backgroundArray = getResources().getIntArray(R.array.widget_presets_values_background); + accentArray = getResources().getIntArray(R.array.widget_presets_values_accent); + titleTextArray = getResources().getIntArray(R.array.widget_presets_values_title_text); setupPreferences(); setName("Appearance Fragment"); } @@ -121,7 +127,7 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin Analytics.from(this).sendPreferenceEvent(key); } - if (key.equals("widget_background_color") || key.equals("widget_text_color") || key.equals("widget_secondary_text_color") || key.equals("widget_icon_color")) { + if (key.equals("widget_background_color") || key.equals("widget_text_color") || key.equals("widget_secondary_text_color") || key.equals("widget_icon_color") || key.equals("widget_title_text_color") || key.equals("widget_list_accent_color")) { Intent nextIntent = new Intent(context, WidgetBroadcastReceiver.class); nextIntent.putExtra("updateUIOnly", true); context.sendBroadcast(nextIntent); @@ -144,14 +150,18 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin private void checkWidgetPreset(Integer arrayPosition) { int backgroundColor = backgroundArray[arrayPosition]; - int primrayTextColor = textPrimaryArray[arrayPosition]; + int primaryTextColor = textPrimaryArray[arrayPosition]; int secondaryTextColor = textSecondaryArray[arrayPosition]; + int accentColor = accentArray[arrayPosition]; + int textTitleColor = titleTextArray[arrayPosition]; Timber.v("Preset # %d", arrayPosition); if (arrayPosition != 8) { widgetBackgroundColor.saveValue(backgroundColor); - widgetTextColor.saveValue(primrayTextColor); + widgetTextColor.saveValue(primaryTextColor); widgetSecondaryTextColor.saveValue(secondaryTextColor); - widgetIconColor.saveValue(primrayTextColor); + widgetIconColor.saveValue(primaryTextColor); + widgetAccentColor.saveValue(accentColor); + widgetTitleColor.saveValue(textTitleColor); isCustomColor = false; Timber.v("Applied widget colors"); } else { @@ -166,6 +176,8 @@ private void setupPreferences() { widgetSecondaryTextColor = (ColorPreference) findPreference("widget_secondary_text_color"); widgetIconColor = (ColorPreference) findPreference("widget_icon_color"); widgetRoundCorners = (SwitchPreference) findPreference("widget_theme_round_corner"); + widgetAccentColor = (ColorPreference) findPreference("widget_list_accent_color"); + widgetTitleColor = (ColorPreference) findPreference("widget_title_text_color"); if (!SupporterHelper.isSupporter()) { Preference weather = findPreference("weather"); weather.setEnabled(false); @@ -199,7 +211,11 @@ private void setupPreferences() { widgetRoundCorners.setEnabled(false); widgetRoundCorners.setSelectable(false); + widgetAccentColor.setEnabled(false); + widgetAccentColor.setSelectable(false); + widgetTitleColor.setEnabled(false); + widgetTitleColor.setSelectable(false); } Preference localTime = findPreference("local_time"); localTime.setOnPreferenceChangeListener(createLocalTimeListener()); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/supporter/SupporterActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/supporter/SupporterActivity.java index d3e68e7a4..58f7fec8c 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/supporter/SupporterActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/supporter/SupporterActivity.java @@ -1,23 +1,23 @@ package me.calebjones.spacelaunchnow.ui.supporter; -import android.animation.Animator; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; +import android.net.Uri; import android.os.Bundle; -import android.os.Handler; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CoordinatorLayout; +import android.support.design.widget.FloatingActionButton; +import android.support.v4.content.ContextCompat; import android.support.v7.widget.AppCompatButton; import android.support.v7.widget.AppCompatSeekBar; import android.support.v7.widget.Toolbar; +import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewAnimationUtils; -import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.TextView; @@ -53,12 +53,15 @@ public class SupporterActivity extends BaseActivity implements BillingProcessor. AppBarLayout appBarLayout; @BindView(R.id.support_thank_you) View supportThankYou; + @BindView(R.id.fab_supporter) + FloatingActionButton fabSupporter; - BillingProcessor bp; - + private BillingProcessor bp; private ImageView icon; private AppCompatSeekBar seekbar; private TextView text; + private boolean isAvailable; + private boolean isRefreshable = true; public SupporterActivity() { super("Supporter Activity"); @@ -85,16 +88,18 @@ protected void onCreate(Bundle savedInstanceState) { purchaseButton.setText("You again? Sure!"); enterReveal(supportThankYou); } else { - purchaseButton.setText("Upgrade to Supporter"); + purchaseButton.setText("Become a Supporter"); } setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); toolbar.setTitle(""); - boolean isAvailable = BillingProcessor.isIabServiceAvailable(context); + isAvailable = BillingProcessor.isIabServiceAvailable(context); if (isAvailable) { // continue bp = new BillingProcessor(this, getResources().getString(R.string.rsa_key), this); + } else { + SnackbarHandler.showErrorSnackbar(this, coordinatorLayout, "Google Play billing services not available."); } } @@ -110,6 +115,50 @@ public boolean onOptionsItemSelected(MenuItem item) { onBackPressed(); } + if (id == R.id.action_restore) { + isRefreshable = true; + restorePurchaseHistory(); + } + + if (id == R.id.action_support) { + new MaterialDialog.Builder(this) + .title("Need Support?") + .content("The fastest and most reliable way to get support is through Discord. If thats not an option feel free to email me directly.") + .neutralText("Email") + .positiveColor(ContextCompat.getColor(this, R.color.colorPrimary)) + .neutralColor(ContextCompat.getColor(this, R.color.colorPrimary)) + .negativeText("Cancel") + .positiveText("Discord") + .onNeutral(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(MaterialDialog dialog, DialogAction which) { + Intent intent = new Intent(Intent.ACTION_SENDTO); + intent.setData(Uri.parse("mailto:")); + intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"support@calebjones.me"}); + intent.putExtra(Intent.EXTRA_SUBJECT, "Space Launch Now - Feedback"); + + startActivity(Intent.createChooser(intent, "Email via...")); + } + }) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(MaterialDialog dialog, DialogAction which) { + String url = "https://discord.gg/WVfzEDW"; + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + startActivity(i); + } + }) + .onNegative(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + dialog.dismiss(); + } + }) + .show(); + + } + return super.onOptionsItemSelected(item); } @@ -121,7 +170,14 @@ public void onDestroy() { } } - @OnClick(R.id.purchase) + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_support, menu); + return true; + } + + @OnClick({R.id.purchase, R.id.fab_supporter}) public void checkClick() { Analytics.from(this).sendButtonClicked("Supporter Button clicked."); MaterialDialog dialog = new MaterialDialog.Builder(this) @@ -136,9 +192,9 @@ public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) }) .show(); - seekbar = (AppCompatSeekBar) dialog.getCustomView().findViewById(R.id.dialog_seekbar); - icon = (ImageView) dialog.getCustomView().findViewById(R.id.dialog_icon); - text = (TextView) dialog.getCustomView().findViewById(R.id.dialog_text); + seekbar = dialog.getCustomView().findViewById(R.id.dialog_seekbar); + icon = dialog.getCustomView().findViewById(R.id.dialog_icon); + text = dialog.getCustomView().findViewById(R.id.dialog_text); setIconPosition(1); seekbar.setProgress(1); @@ -209,12 +265,8 @@ public void onProductPurchased(String productId, TransactionDetails details) { @Override public void onPurchaseHistoryRestored() { - Timber.v("Purchase History restored."); - if (bp != null && bp.listOwnedProducts().size() > 0) { - animatePurchase(); - - SnackbarHandler.showInfoSnackbar(this, coordinatorLayout, "Purchase history restored."); - } + Timber.d("Purchase History restored."); + restorePurchaseHistory(); } @Override @@ -229,13 +281,36 @@ public void onBillingError(int errorCode, Throwable error) { @Override public void onBillingInitialized() { Timber.v("Billing initialized."); - bp.loadOwnedPurchasesFromGoogle(); - for (final String sku : bp.listOwnedProducts()) { - Products product = SupporterHelper.getProduct(sku); - getRealm().beginTransaction(); - getRealm().copyToRealmOrUpdate(product); - getRealm().commitTransaction(); + restorePurchaseHistory(); + } + + private void restorePurchaseHistory() { + if (isAvailable) { + if (isRefreshable) { + isRefreshable = false; + if (bp == null) { + bp = new BillingProcessor(this, getResources().getString(R.string.rsa_key), this); + } + bp.loadOwnedPurchasesFromGoogle(); + if (bp != null && bp.listOwnedProducts().size() > 0) { + animatePurchase(); + Timber.d("Purchase History - Number of items purchased: %s", bp.listOwnedProducts().size()); + for (final String sku : bp.listOwnedProducts()) { + Timber.v("Purchase History - SKU: %s", sku); + Products product = SupporterHelper.getProduct(sku); + getRealm().beginTransaction(); + getRealm().copyToRealmOrUpdate(product); + getRealm().commitTransaction(); + } + SnackbarHandler.showInfoSnackbar(this, coordinatorLayout, "Purchase history restored."); + } else { + Timber.d("Purchase History - None purchased."); + } + } + } else { + SnackbarHandler.showErrorSnackbar(this, coordinatorLayout, "Google Play billing services not available."); } + } @Override diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/UniqueIdentifier.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/UniqueIdentifier.java new file mode 100644 index 000000000..196ab6a25 --- /dev/null +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/UniqueIdentifier.java @@ -0,0 +1,10 @@ +package me.calebjones.spacelaunchnow.utils; + +import java.util.concurrent.atomic.AtomicInteger; + +public class UniqueIdentifier { + private final static AtomicInteger c = new AtomicInteger(0); + public static int getID() { + return c.incrementAndGet(); + } +} diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java index 44e4df5a8..43ce49b0f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java @@ -49,6 +49,7 @@ import java.util.Date; import java.util.Locale; import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicInteger; import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.content.database.ListPreferences; @@ -303,6 +304,94 @@ public static boolean isNetworkAvailable(Context context) { return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting(); } + public static int getCategoryIcon(String type, Boolean night) { + if (type != null) { + switch (type) { + case "Earth Science": + if (night) { + return R.drawable.ic_earth_white; + } else { + return R.drawable.ic_earth; + } + case "Planetary Science": + if (night) { + return R.drawable.ic_planetary_white; + } else { + return R.drawable.ic_planetary; + } + + case "Astrophysics": + if (night) { + return R.drawable.ic_astrophysics_white; + } else { + return R.drawable.ic_astrophysics; + } + + case "Heliophysics": + if (night) { + return R.drawable.ic_heliophysics_alt_white; + } else { + return R.drawable.ic_heliophysics_alt; + } + + case "Human Exploration": + if (night) { + return R.drawable.ic_human_explore_white; + } else { + return R.drawable.ic_human_explore; + } + case "Robotic Exploration": + if (night) { + return R.drawable.ic_robotic_explore_white; + } else { + return R.drawable.ic_robotic_explore; + } + case "Government/Top Secret": + if (night) { + return R.drawable.ic_top_secret_white; + } else { + return R.drawable.ic_top_secret; + } + case "Tourism": + if (night) { + return R.drawable.ic_tourism_white; + } else { + return R.drawable.ic_tourism; + } + case "Unknown": + if (night) { + return R.drawable.ic_unknown_white; + } else { + return R.drawable.ic_unknown; + } + case "Communications": + if (night) { + return R.drawable.ic_satellite_white; + } else { + return R.drawable.ic_satellite; + } + case "Resupply": + if (night) { + return R.drawable.ic_resupply_white; + } else { + return R.drawable.ic_resupply; + } + default: + if (night) { + return R.drawable.ic_unknown_white; + } else { + return R.drawable.ic_unknown; + } + } + } else { + if (night) { + return R.drawable.ic_unknown_white; + } else { + return R.drawable.ic_unknown; + } + } + } + public static void setCategoryIcon(ImageView imageView, String type, Boolean night) { if (type != null) { switch (type) { @@ -515,4 +604,5 @@ public static Bitmap getBitMapFromUrl(Context context, String imageURL) { return null; } } -} \ No newline at end of file +} + diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/WidgetJobService.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/WidgetJobService.java index 3359150ea..c6272d89f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/WidgetJobService.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/WidgetJobService.java @@ -10,6 +10,8 @@ import me.calebjones.spacelaunchnow.content.jobs.SyncWidgetJob; import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactManager; import me.calebjones.spacelaunchnow.widget.launchcard.UpdateLaunchCardJob; +import me.calebjones.spacelaunchnow.widget.launchlist.LaunchListManager; +import me.calebjones.spacelaunchnow.widget.launchlist.LaunchListWidgetProvider; import me.calebjones.spacelaunchnow.widget.wordtimer.LaunchWordTimerManager; import me.calebjones.spacelaunchnow.widget.wordtimer.UpdateWordTimerJob; import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactWidgetProvider; @@ -31,6 +33,7 @@ protected void onHandleWork(@NonNull Intent intent) { Context context = getApplicationContext(); LaunchCardCompactManager launchCardCompactManager = new LaunchCardCompactManager(context); LaunchWordTimerManager launchWordTimerManager = new LaunchWordTimerManager(context); + LaunchListManager launchListManager = new LaunchListManager(context); if (intent.hasExtra("updateUIOnly") && intent.getBooleanExtra("updateUIOnly", false)){ int cardIds[] = AppWidgetManager.getInstance(context) .getAppWidgetIds(new ComponentName(context, @@ -47,6 +50,14 @@ protected void onHandleWork(@NonNull Intent intent) { for (int id : timerIds){ launchWordTimerManager.updateAppWidget(id); } + + int listIds[] = AppWidgetManager.getInstance(context) + .getAppWidgetIds(new ComponentName(context, + LaunchListWidgetProvider.class)); + + for (int id : listIds){ + launchListManager.updateAppWidget(id); + } } else { SyncWidgetJob.scheduleImmediately(); } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java index 4af575b87..8294fb3c1 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java @@ -15,6 +15,7 @@ import java.util.Date; import io.realm.Realm; +import io.realm.RealmQuery; import io.realm.RealmResults; import io.realm.Sort; import me.calebjones.spacelaunchnow.R; @@ -22,6 +23,7 @@ import me.calebjones.spacelaunchnow.content.util.QueryBuilder; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; +import me.calebjones.spacelaunchnow.utils.UniqueIdentifier; import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; import timber.log.Timber; @@ -51,9 +53,12 @@ private Launch getLaunch() { RealmResults launchRealms; if (switchPreferences.getAllSwitch()) { - launchRealms = mRealm.where(Launch.class) - .greaterThanOrEqualTo("net", date) - .findAllSorted("net", Sort.ASCENDING); + RealmQuery query = mRealm.where(Launch.class) + .greaterThanOrEqualTo("net", date); + if (switchPreferences.getNoGoSwitch()) { + query.equalTo("status", 1); + } + launchRealms = query.findAllSorted("net", Sort.ASCENDING); Timber.v("loadLaunches - Realm query created."); } else { launchRealms = QueryBuilder.buildSwitchQuery(context, mRealm); @@ -61,7 +66,7 @@ private Launch getLaunch() { } for (Launch launch : launchRealms) { - if (launch.getNetstamp() != null && launch.getNetstamp() != 0) { + if (launch.getNet() != null) { return launch; } } @@ -69,7 +74,7 @@ private Launch getLaunch() { } public void updateAppWidget(int appWidgetId) { - Timber.v("UpdateAppWidget"); + Timber.v("UpdateAppWidget %s", appWidgetId); Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId); int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH); int maxWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH); @@ -80,7 +85,7 @@ public void updateAppWidget(int appWidgetId) { Launch launch = getLaunch(); - if (minWidth <= 200 || minHeight <= 100) { + if (minWidth <= 220 || minHeight <= 100) { remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_launch_card_compact_small_dark); } else if (minWidth <= 320) { @@ -114,8 +119,7 @@ private void setRefreshIntent(Launch launch) { Intent exploreIntent = new Intent(context, LaunchDetailActivity.class); exploreIntent.putExtra("TYPE", "launch"); exploreIntent.putExtra("launchID", launch.getId()); - exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - PendingIntent actionPendingIntent = PendingIntent.getActivity(context, 0, exploreIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent actionPendingIntent = PendingIntent.getActivity(context, UniqueIdentifier.getID(), exploreIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.widget_compact_card_frame, actionPendingIntent); } @@ -125,21 +129,25 @@ private void setWidgetStyle() { int colorWhite = 0xFFFFFFFF; int colorSecondaryWhite = 0xB3FFFFFF; int colorBackground = 0xFF303030; - boolean widgetRounderCorners = sharedPref.getBoolean("widget_theme_round_corner", true); int widgetTextColor = sharedPref.getInt("widget_text_color",colorWhite); int widgetBackgroundColor = sharedPref.getInt("widget_background_color", colorBackground); int widgetSecondaryTextColor = sharedPref.getInt("widget_secondary_text_color",colorSecondaryWhite); - int widgetIconColor = sharedPref.getInt("widget_icon_color",colorWhite); - if(widgetRounderCorners) + int widgetIconColor = sharedPref.getInt("widget_icon_color", colorWhite); + + if(sharedPref.getBoolean("widget_theme_round_corner", true)) remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded); else remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.squared); Timber.v("Configuring widget"); int widgetAlpha = Color.alpha(widgetBackgroundColor); - remoteViews.setInt(R.id.bgcolor, "setColorFilter", widgetBackgroundColor); + int red = Color.red(widgetBackgroundColor); + int green = Color.green(widgetBackgroundColor); + int blue = Color.blue(widgetBackgroundColor); + remoteViews.setInt(R.id.bgcolor, "setColorFilter", Color.rgb(red,green,blue)); remoteViews.setInt(R.id.bgcolor, "setAlpha", widgetAlpha); - remoteViews.setTextColor(R.id.widget_launch_rocket, widgetTextColor); + remoteViews.setTextColor(R.id.widget_launch_mission, widgetTextColor); + remoteViews.setTextColor(R.id.widget_launch_rocket, widgetSecondaryTextColor); remoteViews.setTextColor(R.id.widget_location, widgetSecondaryTextColor); remoteViews.setTextColor(R.id.widget_launch_date, widgetSecondaryTextColor); remoteViews.setInt(R.id.widget_categoryIcon, "setColorFilter", widgetIconColor); @@ -161,12 +169,26 @@ private void setLocationName(Launch launchRealm) { } private void setLaunchName(Launch launchRealm) { - String launchName = getLaunchName(launchRealm); + String title[]; + if (launchRealm.getName() != null) { + title = launchRealm.getName().split("\\|"); + try { + if (title.length > 0) { + remoteViews.setTextViewText(R.id.widget_launch_rocket, title[0].trim()); + remoteViews.setTextViewText(R.id.widget_launch_mission, title[1].trim()); + } else { + remoteViews.setTextViewText(R.id.widget_launch_rocket, launchRealm.getName()); + if (launchRealm.getMissions().size() > 0) { + remoteViews.setTextViewText(R.id.widget_launch_mission, launchRealm.getMissions().get(0).getName()); + } + } + } catch (ArrayIndexOutOfBoundsException exception) { + remoteViews.setTextViewText(R.id.widget_launch_rocket, launchRealm.getName()); + if (launchRealm.getMissions().size() > 0) { + remoteViews.setTextViewText(R.id.widget_launch_mission, launchRealm.getMissions().get(0).getName()); + } - if (launchName != null) { - remoteViews.setTextViewText(R.id.widget_launch_rocket, launchName); - } else { - remoteViews.setTextViewText(R.id.widget_launch_rocket, "Unknown Launch"); + } } } @@ -193,16 +215,6 @@ private void setCategoryIcon(Launch launch) { } } - private String getLaunchName(Launch launchRealm) { - //Replace with launch - if (launchRealm.getRocket() != null && launchRealm.getRocket().getName() != null) { - //Replace with mission name - return launchRealm.getRocket().getName(); - } else { - return null; - } - } - private String getMissionName(Launch launchRealm) { if (launchRealm.getMissions().size() > 0) { @@ -218,11 +230,6 @@ private long getFutureMilli(Launch launchRealm) { } private Calendar getLaunchDate(Launch launchRealm) { - - //Replace with launchData - long longdate = launchRealm.getNetstamp(); - longdate = longdate * 1000; - final Date date = new Date(longdate); - return Utils.DateToCalendar(date); + return Utils.DateToCalendar(launchRealm.getNet()); } } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java new file mode 100644 index 000000000..956ff45cc --- /dev/null +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java @@ -0,0 +1,215 @@ +package me.calebjones.spacelaunchnow.widget.launchlist; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.preference.PreferenceManager; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import io.realm.Realm; +import io.realm.RealmList; +import io.realm.RealmQuery; +import io.realm.RealmResults; +import io.realm.Sort; +import me.calebjones.spacelaunchnow.R; +import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; +import me.calebjones.spacelaunchnow.content.util.QueryBuilder; +import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; +import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; +import me.calebjones.spacelaunchnow.utils.Utils; +import timber.log.Timber; + + +public class LaunchListFactory implements RemoteViewsService.RemoteViewsFactory { + + private Context context; + private int appWidgetId; + private SwitchPreferences switchPreferences; + private SharedPreferences sharedPref; + private List launches = new RealmList<>(); + + public LaunchListFactory(Context context, Intent intent) { + this.context = context; + appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + Timber.d("AppWidgetId: %s", appWidgetId); + switchPreferences = SwitchPreferences.getInstance(context); + sharedPref = PreferenceManager.getDefaultSharedPreferences(context); + } + + private void initData() { + Timber.d("Init Data for Widget %s", appWidgetId); + launches = new RealmList<>(); + Realm mRealm = Realm.getDefaultInstance(); + launches = getLaunches(mRealm); + mRealm.close(); + } + + private List getLaunches(Realm mRealm) { + Timber.d("Getting launches."); + Date date = new Date(); + + RealmResults launchRealms; + if (switchPreferences.getAllSwitch()) { + RealmQuery query = mRealm.where(Launch.class) + .greaterThanOrEqualTo("net", date); + if (switchPreferences.getNoGoSwitch()) { + query.equalTo("status", 1); + } + launchRealms = query.findAllSorted("net", Sort.ASCENDING); + Timber.v("loadLaunches - Realm query created."); + } else { + launchRealms = QueryBuilder.buildSwitchQuery(context, mRealm); + Timber.v("loadLaunches - Filtered Realm query created - size: %s", launchRealms.size()); + } + + for (Launch launch : launchRealms) { + Timber.v("Launch: %s", launch.getName()); + if (launches.size() <= 20) { + launches.add(launch); + } + } + Timber.v("Final Launches size: %s", launches.size()); + return mRealm.copyFromRealm(launches); + } + + @Override + public void onCreate() { + initData(); + } + + @Override + public void onDataSetChanged() { + initData(); + } + + @Override + public void onDestroy() { + + } + + @Override + public int getCount() { + return (launches.size()); + } + + @Override + public RemoteViews getViewAt(int position) { + Launch launch = launches.get(position); + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); + int colorWhite = 0xFFFFFFFF; + int colorSecondaryWhite = 0xB3FFFFFF; + int colorBackground = 0xFF303030; + int widgetPrimaryTextColor = sharedPref.getInt("widget_text_color",colorWhite); + int widgetBackgroundColor = sharedPref.getInt("widget_background_color", colorBackground); + int widgetSecondaryTextColor = sharedPref.getInt("widget_secondary_text_color",colorSecondaryWhite); + int widgetIconsColor = sharedPref.getInt("widget_icon_color",colorWhite); + int widgetAlpha = Color.alpha(widgetBackgroundColor); + Timber.v("LaunchListFactory - binding view at %s for launch %s", position, launch.getName()); + RemoteViews row = new RemoteViews(context.getPackageName(), R.layout.launch_list_item); + String[] title; + String launchDate; + SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); + + //Retrieve missionType + if (launch.getMissions().size() != 0) { + row.setImageViewResource(R.id.categoryIcon, Utils.getCategoryIcon(launch.getMissions().get(0).getTypeName(), false)); + } else { + row.setImageViewResource(R.id.categoryIcon, R.drawable.ic_unknown); + } + row.setInt(R.id.categoryIcon, "setColorFilter", widgetIconsColor); + row.setTextColor(R.id.launch_rocket, widgetPrimaryTextColor); + row.setTextColor(R.id.mission, widgetSecondaryTextColor); + row.setTextColor(R.id.launch_date, widgetSecondaryTextColor); + row.setTextColor(R.id.location, widgetSecondaryTextColor); + + if (launch.getStatus() != null && launch.getStatus() == 2) { + //Get launch date + sdf.setTimeZone(TimeZone.getTimeZone("UTC")); + Date date = launch.getNet(); + launchDate = sdf.format(date); + + row.setTextViewText(R.id.launch_date, String.format("%s (Unconfirmed)", launchDate)); + } else { + //Get launch date + if (sharedPref.getBoolean("local_time", true)) { + + sdf.toLocalizedPattern(); + Date date = launch.getNet(); + launchDate = sdf.format(date); + } else { + sdf.setTimeZone(TimeZone.getTimeZone("UTC")); + Date date = launch.getNet(); + launchDate = sdf.format(date); + } + row.setTextViewText(R.id.launch_date, launchDate); + } + + if (launch.getName() != null) { + title = launch.getName().split("\\|"); + try { + if (title.length > 0) { + row.setTextViewText(R.id.launch_rocket, title[1].trim()); + row.setTextViewText(R.id.mission, title[0].trim()); + } else { + row.setTextViewText(R.id.launch_rocket, launch.getName()); + if (launch.getMissions().size() > 0) { + row.setTextViewText(R.id.mission, launch.getMissions().get(0).getName()); + } + } + } catch (ArrayIndexOutOfBoundsException exception) { + row.setTextViewText(R.id.launch_rocket, launch.getName()); + if (launch.getMissions().size() > 0) { + row.setTextViewText(R.id.mission, launch.getMissions().get(0).getName()); + } + + } + } + + //If pad and agency exist add it to location, otherwise get whats always available + if (launch.getLocation() != null) { + row.setTextViewText(R.id.location, launch.getLocation().getName()); + } else { + row.setTextViewText(R.id.location, "Click for more information."); + } + row.setTextViewText(R.id.location, launch.getLocation().getName()); + + Intent exploreIntent = new Intent(context, LaunchDetailActivity.class); + exploreIntent.putExtra("TYPE", "launch"); + exploreIntent.putExtra("launchID", launch.getId()); + exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + + row.setOnClickFillInIntent(R.id.rootview, exploreIntent); + + return (row); + } + + @Override + public RemoteViews getLoadingView() { + return null; + } + + @Override + public int getViewTypeCount() { + return (1); + } + + @Override + public long getItemId(int position) { + return (position); + } + + @Override + public boolean hasStableIds() { + return (true); + } +} diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java new file mode 100644 index 000000000..5ef3cd0c9 --- /dev/null +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java @@ -0,0 +1,167 @@ +package me.calebjones.spacelaunchnow.widget.launchlist; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.net.Uri; +import android.preference.PreferenceManager; +import android.widget.RemoteViews; + +import me.calebjones.spacelaunchnow.R; +import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; +import me.calebjones.spacelaunchnow.ui.main.MainActivity; +import me.calebjones.spacelaunchnow.ui.supporter.SupporterHelper; +import me.calebjones.spacelaunchnow.utils.UniqueIdentifier; +import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; +import timber.log.Timber; + + +public class LaunchListManager { + + private Context context; + private AppWidgetManager appWidgetManager; + + public LaunchListManager(Context context) { + this.context = context; + appWidgetManager = AppWidgetManager.getInstance(context); + } + + public void updateAppWidget(int appWidgetId) { + Timber.d("Updating appWidgetId %s", appWidgetId); + if (SupporterHelper.isSupporter()) { + buildWidget(appWidgetId); + } else { + buildSupporterWidget(appWidgetId); + } + + } + + private void buildSupporterWidget(int appWidgetId) { + Timber.d("Building Support layout - %s", appWidgetId); + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); + RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_become_supporter); + int colorWhite = 0xFFFFFFFF; + int colorSecondaryWhite = 0xB3FFFFFF; + int colorBackground = 0xFF303030; + int colorAccent = 0xFF455a64; + int widgetPrimaryTextColor = sharedPref.getInt("widget_text_color", colorWhite); + int widgetAccentColor = sharedPref.getInt("widget_list_accent_color", colorAccent); + int widgetBackgroundColor = sharedPref.getInt("widget_background_color", colorBackground); + int widgetSecondaryTextColor = sharedPref.getInt("widget_secondary_text_color", colorSecondaryWhite); + int widgetTitleTextColor = sharedPref.getInt("widget_title_text_color", colorWhite); + int widgetIconsColor = sharedPref.getInt("widget_icon_color", colorWhite); + + if (sharedPref.getBoolean("widget_theme_round_corner", true)) { + remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded); + remoteViews.setImageViewResource(R.id.title_background, R.drawable.rounded_top); + } else { + remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.squared); + remoteViews.setImageViewResource(R.id.title_background, R.drawable.squared); + } + + remoteViews.setTextColor(R.id.title, widgetTitleTextColor); + int widgetAlpha = Color.alpha(widgetBackgroundColor); + int red = Color.red(widgetBackgroundColor); + int green = Color.green(widgetBackgroundColor); + int blue = Color.blue(widgetBackgroundColor); + remoteViews.setInt(R.id.bgcolor, "setColorFilter", Color.rgb(red,green,blue)); + remoteViews.setInt(R.id.bgcolor, "setAlpha", widgetAlpha); + + red = Color.red(widgetAccentColor); + green = Color.green(widgetAccentColor); + blue = Color.blue(widgetAccentColor); + remoteViews.setInt(R.id.title_background, "setColorFilter", Color.rgb(red,green,blue)); + remoteViews.setInt(R.id.title_background, "setAlpha", widgetAlpha); + + remoteViews.setInt(R.id.widget_refresh_button, "setColorFilter", widgetTitleTextColor); + + remoteViews.setTextColor(R.id.supporter_message, widgetPrimaryTextColor); + remoteViews.setTextViewText(R.id.title, "Space Launch Now"); + remoteViews.setImageViewResource(R.id.widget_refresh_button, R.drawable.ic_refresh_black); + + Intent nextIntent = new Intent(context, WidgetBroadcastReceiver.class); + PendingIntent refreshPending = PendingIntent.getBroadcast(context, 0, nextIntent, 0); + remoteViews.setOnClickPendingIntent(R.id.widget_refresh_button, refreshPending); + + Intent openAppIntent = new Intent(context, MainActivity.class); + openAppIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + PendingIntent actionPendingIntent = PendingIntent.getActivity(context, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + remoteViews.setOnClickPendingIntent(R.id.title, actionPendingIntent); + + appWidgetManager.updateAppWidget(appWidgetId, remoteViews); + } + + private void buildWidget(int appWidgetId) { + Timber.d("Building full layout - %s", appWidgetId); + + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); + + RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_launch_list); + + int colorWhite = 0xFFFFFFFF; + int colorSecondaryWhite = 0xB3FFFFFF; + int colorBackground = 0xFF303030; + int colorAccent = 0xFF455a64; + int widgetPrimaryTextColor = sharedPref.getInt("widget_text_color", colorWhite); + int widgetAccentColor = sharedPref.getInt("widget_list_accent_color", colorAccent); + int widgetBackgroundColor = sharedPref.getInt("widget_background_color", colorBackground); + int widgetSecondaryTextColor = sharedPref.getInt("widget_secondary_text_color", colorSecondaryWhite); + int widgetTitleTextColor = sharedPref.getInt("widget_title_text_color", colorWhite); + int widgetIconsColor = sharedPref.getInt("widget_icon_color", colorWhite); + + if (sharedPref.getBoolean("widget_theme_round_corner", true)) { + remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded); + remoteViews.setImageViewResource(R.id.title_background, R.drawable.rounded_top); + } else { + remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.squared); + remoteViews.setImageViewResource(R.id.title_background, R.drawable.squared); + } + remoteViews.setTextColor(R.id.title, widgetTitleTextColor); + + int widgetAlpha = Color.alpha(widgetBackgroundColor); + int red = Color.red(widgetBackgroundColor); + int green = Color.green(widgetBackgroundColor); + int blue = Color.blue(widgetBackgroundColor); + remoteViews.setInt(R.id.bgcolor, "setColorFilter", Color.rgb(red,green,blue)); + remoteViews.setInt(R.id.bgcolor, "setAlpha", widgetAlpha); + + red = Color.red(widgetAccentColor); + green = Color.green(widgetAccentColor); + blue = Color.blue(widgetAccentColor); + remoteViews.setInt(R.id.title_background, "setColorFilter", Color.rgb(red,green,blue)); + remoteViews.setInt(R.id.title_background, "setAlpha", widgetAlpha); + remoteViews.setInt(R.id.widget_refresh_button, "setColorFilter", widgetTitleTextColor); + + Intent svcIntent = new Intent(context, LaunchListWidgetService.class); + svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME))); + + remoteViews.setRemoteAdapter(R.id.launch_list, svcIntent); + remoteViews.setTextViewText(R.id.title, "Space Launch Now"); + remoteViews.setImageViewResource(R.id.widget_refresh_button, R.drawable.ic_refresh_black); + + Intent nextIntent = new Intent(context, WidgetBroadcastReceiver.class); + PendingIntent refreshPending = PendingIntent.getBroadcast(context, 0, nextIntent, 0); + remoteViews.setOnClickPendingIntent(R.id.widget_refresh_button, refreshPending); + + Intent openAppIntent = new Intent(context, MainActivity.class); + openAppIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + PendingIntent actionPendingIntent = PendingIntent.getActivity(context, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + remoteViews.setOnClickPendingIntent(R.id.title, actionPendingIntent); + + Intent clickIntent = new Intent(context, LaunchDetailActivity.class); + PendingIntent clickPI = PendingIntent + .getActivity(context, UniqueIdentifier.getID(), + clickIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + remoteViews.setPendingIntentTemplate(R.id.launch_list, clickPI); + + appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.launch_list); + appWidgetManager.updateAppWidget(appWidgetId, remoteViews); + } +} diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListWidgetProvider.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListWidgetProvider.java new file mode 100644 index 000000000..4cd49293f --- /dev/null +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListWidgetProvider.java @@ -0,0 +1,60 @@ +package me.calebjones.spacelaunchnow.widget.launchlist; + +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; +import me.calebjones.spacelaunchnow.widget.launchcard.LaunchCardCompactManager; +import timber.log.Timber; + + +public class LaunchListWidgetProvider extends AppWidgetProvider { + + public static String ACTION_WIDGET_REFRESH = "ActionReceiverRefresh"; + public static String ACTION_WIDGET_CLICK = "ActionReceiverClick"; + + @Override + public void onEnabled(Context context) { + // Enter relevant functionality for when the first widget is created + Intent nextIntent = new Intent(context, WidgetBroadcastReceiver.class); + nextIntent.putExtra("updateUIOnly", true); + context.sendBroadcast(nextIntent); + } + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + Timber.v("onUpdate"); + LaunchListManager launchListManager = new LaunchListManager(context); + for (int widgetId : appWidgetIds) { + launchListManager.updateAppWidget(widgetId); + } + + } + + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(ACTION_WIDGET_REFRESH)) { + Timber.v("onReceive %s", ACTION_WIDGET_REFRESH); + AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); + int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, this.getClass())); + onUpdate(context, appWidgetManager, appWidgetIds); + } else if (intent.getAction().equals(ACTION_WIDGET_CLICK)) { + Timber.v("onReceive %s", ACTION_WIDGET_CLICK); + } else { + super.onReceive(context, intent); + } + } + + @Override + public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, + int appWidgetId, Bundle newOptions) { + LaunchListManager launchListManager = new LaunchListManager(context); + launchListManager.updateAppWidget(appWidgetId); + super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); + } + +} diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListWidgetService.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListWidgetService.java new file mode 100644 index 000000000..8338ec751 --- /dev/null +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListWidgetService.java @@ -0,0 +1,15 @@ +package me.calebjones.spacelaunchnow.widget.launchlist; + +import android.content.Intent; +import android.widget.RemoteViewsService; + +import timber.log.Timber; + +public class LaunchListWidgetService extends RemoteViewsService { + + @Override + public RemoteViewsFactory onGetViewFactory(Intent intent) { + Timber.v("onGetViewFactory - Intent received."); + return(new LaunchListFactory(this.getApplicationContext(), intent)); + } +} \ No newline at end of file diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/UpdateLaunchListJob.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/UpdateLaunchListJob.java new file mode 100644 index 000000000..a2900af12 --- /dev/null +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/UpdateLaunchListJob.java @@ -0,0 +1,40 @@ +package me.calebjones.spacelaunchnow.widget.launchlist; + +import android.content.Context; +import android.support.annotation.NonNull; + +import com.evernote.android.job.Job; +import com.evernote.android.job.JobRequest; +import com.evernote.android.job.util.support.PersistableBundleCompat; + +import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; +import me.calebjones.spacelaunchnow.data.models.Constants; + +public class UpdateLaunchListJob extends Job { + + public static final String TAG = Constants.ACTION_UPDATE_LAUNCH_LIST; + public SwitchPreferences switchPreferences; + private Context context; + + @NonNull + @Override + protected Job.Result onRunJob(Job.Params params) { + context = getContext(); + PersistableBundleCompat extras = params.getExtras(); + int appWidgetId = extras.getInt("appWidgetId", 0); + LaunchListManager launchListManager = new LaunchListManager(context); + launchListManager.updateAppWidget(appWidgetId); + return Job.Result.SUCCESS; + } + + public static void runJobImmediately(int id) { + PersistableBundleCompat extras = new PersistableBundleCompat(); + extras.putInt("appWidgetId", id); + new JobRequest.Builder(UpdateLaunchListJob.TAG) + .addExtras(extras) + .startNow() + .build() + .schedule(); + } + +} diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java index 8ef2baf3a..2f19403c0 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java @@ -15,6 +15,7 @@ import java.util.Date; import io.realm.Realm; +import io.realm.RealmQuery; import io.realm.RealmResults; import io.realm.Sort; import me.calebjones.spacelaunchnow.R; @@ -22,6 +23,7 @@ import me.calebjones.spacelaunchnow.content.util.QueryBuilder; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; +import me.calebjones.spacelaunchnow.utils.UniqueIdentifier; import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; import timber.log.Timber; @@ -40,7 +42,7 @@ public LaunchWordTimerManager(Context context){ } public void updateAppWidget(int appWidgetId) { - Timber.v("UpdateAppWidget"); + Timber.v("UpdateAppWidget %s", appWidgetId); Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId); int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH); int maxWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH); @@ -90,9 +92,12 @@ private Launch getLaunch(Context context) { RealmResults launchRealms; if (switchPreferences.getAllSwitch()) { - launchRealms = mRealm.where(Launch.class) - .greaterThanOrEqualTo("net", date) - .findAllSorted("net", Sort.ASCENDING); + RealmQuery query = mRealm.where(Launch.class) + .greaterThanOrEqualTo("net", date); + if (switchPreferences.getNoGoSwitch()) { + query.equalTo("status", 1); + } + launchRealms = query.findAllSorted("net", Sort.ASCENDING); Timber.v("loadLaunches - Realm query created."); } else { launchRealms = QueryBuilder.buildSwitchQuery(context, mRealm); @@ -100,7 +105,7 @@ private Launch getLaunch(Context context) { } for (Launch launch : launchRealms) { - if (launch.getNetstamp() != null && launch.getNetstamp() != 0) { + if (launch.getNet() != null) { return launch; } } @@ -116,7 +121,7 @@ private void setRefreshIntent(Launch launch) { exploreIntent.putExtra("TYPE", "launch"); exploreIntent.putExtra("launchID", launch.getId()); exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - PendingIntent actionPendingIntent = PendingIntent.getActivity(context, 0, exploreIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent actionPendingIntent = PendingIntent.getActivity(context, UniqueIdentifier.getID(), exploreIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.widget_countdown_timer_frame, actionPendingIntent); } @@ -163,7 +168,10 @@ private void setWidgetStyle() { Timber.v("Configuring widget"); int widgetAlpha = Color.alpha(widgetBackgroundColor); - remoteViews.setInt(R.id.bgcolor, "setColorFilter", widgetBackgroundColor); + int red = Color.red(widgetBackgroundColor); + int green = Color.green(widgetBackgroundColor); + int blue = Color.blue(widgetBackgroundColor); + remoteViews.setInt(R.id.bgcolor, "setColorFilter", Color.rgb(red,green,blue)); remoteViews.setInt(R.id.bgcolor, "setAlpha", widgetAlpha); remoteViews.setTextColor(R.id.widget_launch_name, widgetTextColor); remoteViews.setTextColor(R.id.widget_mission_name, widgetSecondaryTextColor); @@ -225,11 +233,6 @@ private long getFutureMilli(Launch launchRealm) { } private Calendar getLaunchDate(Launch launchRealm) { - - //Replace with launchData - long longdate = launchRealm.getNetstamp(); - longdate = longdate * 1000; - final Date date = new Date(longdate); - return Utils.DateToCalendar(date); + return Utils.DateToCalendar(launchRealm.getNet()); } } diff --git a/mobile/src/main/res/drawable/ic_money.xml b/mobile/src/main/res/drawable/ic_money.xml new file mode 100644 index 000000000..3d7df7cca --- /dev/null +++ b/mobile/src/main/res/drawable/ic_money.xml @@ -0,0 +1,9 @@ + + + diff --git a/mobile/src/main/res/drawable/launch_card_compact_preview.png b/mobile/src/main/res/drawable/launch_card_compact_preview.png deleted file mode 100755 index 4b71900656406f8d9d7c2c03e5ad7ff0305f79fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12936 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 Ra diff --git a/mobile/src/main/res/drawable/launch_card_preview.webp b/mobile/src/main/res/drawable/launch_card_preview.webp new file mode 100644 index 0000000000000000000000000000000000000000..4cbb2674505971bf467c463667ed9bd2e15a31f0 GIT binary patch literal 41980 zcma&M1C(UZk~N%V8(p?-c3EAvZChQo*=5_d-Bn$-ZQHK=d-Q*A=FO~`yE5;}%yrI* zSP^kz?|t$rNs5a<6aoP1V!{e)3S1hn0002_?^^%@kP8YBl2P~}`S%+L5)%*wMVOdO zatb@E_Yk{F2oZl42m=k=Hmr2Df6E2F{;#j?(*s~8E#R*WqTs*wn0P?5L1+Xa@<92q z;X{P-!L@Y1g98ld>DL_z2mGRZF~1JKfG@V_AL=j9Px5oqr@d#rexK5x{2#p^P*3(J zxifxSU%+RO5BVFgYhX1cHIVtE_QrY#?v`;UcLdn-l?~Jc+I|KBpJsjnzQjHf-&&up zuL*N=&ptMR7$5YXz!%CJzYD_1-ifb1fjB?%ug1^&5BV3Q8+{<~$fxUzaddo5;0&1X z1ojd3rv7q$BhZ`FEJao8LC@MITXs=xh2*`9t6p_@v(pyz&G0!}v1(Tz@Zp zxqbxp0Kp+s}i}ywObKV>5Mg1oCU^_^!Paydf z;Po$K5kAy!S{KdlkopC*wqyKkz7$`W@1R}?Z|wJT*Zq2cbYJ7I+%F&>U>jhM?(gnx z-%j-JuP+5QfZV;zl5so0A%QeMiBF}^1|S%)^uBe-kM7Isv-2_PE%l@J4*1+1=DmJz ze?_?E*Y0NkjQZ05DxLdwon!rd`c;6fH|&%5&HhpUCU@7b!|w{n3S7Pe9s`$p8@|SY zUZ2fR>UV^@y=}h6esQl5AB-0)f*n#qYJRaW{U)z)PV2-yfp(kPh|N{1$id>OKBfPCMpnCB->!v8~9U0m*da&5LQfF4Y(t2|2W`Tl38|6e@*F$#Q&!h`>slmB%v5eVzw;0c^s z@}o^{=P@N!&lCN^i!_wax47Iu_?Iky3t}T7`X1}QIQU-^@Yi5YS-z1pnzb_0A#H=n zS>Z<_LDkFv&3J>(>-l`rwZjzQ<8~Fd3)kLqN8*w&fx7E&*3>3msvi2*ozjjTQfuHo z$+O1`dXtHhBMd9Mv~+-C+&|}@wp4Cj6WWv>+x10m{t0f7FVAonfA_8_Gby*m-I$3O z)X>H|K0zCw;kOLUTsRq%mJX6}W2oxxJ&6e4$w-CMlDi*s#w=ezM`vz%Bt5^L+j0iK zjcqelJ8@V+faX8djTyNL+;x!c_X=*TfjJ4jBDmVdR3Ok6&1F9vz2oS^rRe;&+X|}+ zQydwb-_~Us&kRWN*+tBhswmb$fScbnBlOh@i*Vc6F9ADNGZ19W&AMwLTpq30FMFly zb(8)m4)@Qs`p2^%B!U12wl%e1-*rndkeVks5Wn%LRKXT4it9)(s*ZNF;i4?N&Z{@3 zv+-ultt2c%$EhURSq^vdr-_124#V}5gFOTX))L4{z;le)UcUs0T0a+AX>mRGKNiKm zZegC@)z55NQN2Tzu5B!_CB;?$u4uR`!B|eY?tW$jU$^E#sho&yf0Pw(2Qx0$upqz<1bZx^LSYZq4gC2Z z`whhwox(eF?5kgohW~F&StR&C{_BV~%0U~SMgQDw7|Dg%k6)a}SHg8FPeu~%2V`%< zu8?`Z;V@i`cdljOTSk76<0bv;24M&0&wvlsoFM4@M{B!Ab`Mc4-|)fCiYY5fsc)bl zcKASGb=yBLZdRHu%dFN)2jj9}bC7B;n0ouuOl38VgC)vK#@roeJVx?+8l>9*?a#-B zL#^mft%>^iP=~NbiBIl2w2GyoVuZ(pho(cF8kYQ#{w-5Ez4nH{^6DcKAbXQ=ElN%#AC0d{&r21tCUY==|-8wg;==_v&H#PrGION zgB1bZ;SKtWu@j#Fo4s(F77vF;&g92UZ_&a}r!IOmtzvzAxZ|NN5L)Lg=wQ-uaM|{= za`mx!ry>}PfP|yz3ibh`q+fyT=W|LMG0T#a&BU{IFCr;YE{SEQs>M=(=|Nw~Z`rHn zL2ojxkc%N~;u2MY1{?sDmu14)t{p}oI@!3vo)ev-i7_52M;T#fkaB0XQslt^@L_eV z;wxm+W<36p23;<+JRcleUmlF)riTEdcslH|iq8XMBck%(AjGfn>Wqgp4C);~b<#Y* z5XQ(4)YZ*R^wg^#Z1#KQ%F>jWT#xlqNn%vHOvsD&Bxyw!M~ zTmiopv=1ckN5&9?q(B>hc|5Rse_D z)d$UzjMsf33icN=_r%Es36Wr-7BY!DW2}4u`wh?rtAoV?L$mAJzrg4tuU&s{PMB``_^z30Ney6gu@A zH1G+82{R@7SZ_xBMAwc>3YC3b`%I8>atI2%V^_<2G)h4DkNj593Ek+E2OXWPx#Zwgb!1ChjO8J!g+UHf7_ncC!xG5Do*86_0x}qeL`hCc>MWyV(^7}b!+BiHq#8{0 zWs8L%{bB*wQ!H}l4vG*6bZ@(gA;N3}-D-dN31*m_*rPu4liEp3PhT>B&oeS!fK~j0 z?<`-SF5IRq!God|B0ndeE(g*03tdEoPUlyOQ}VCx##G+5HzC4p3u$E zFvJC{h`U_u-07*3(@)7NeHjJb2f)!P;=ZE60q3osqt&zg32EI_gMObl1G+yie~f{DfRGdKpkqtfAbPRNPKWd8_kMJTX;qFSyiF-CJYPOrC*8kp}T;Gk? z)f!FgXNRHD!~n|r(fB-P)VxhW#1woq;Wc92v+z>{H*(eG1UY0$Zm8+=ISX6-{L%BGs0hvOWNXAR~#K zX|xN8>4FxCf`8dB>moXxa8ex9gLLnFKqSo1dVOvWYMUBE$k{=fA)Q}uMc~KyvwB=D zTnBc|whqlFoQ7WQoDYTn^Ue(FdQa>FybZ6%RhB6KKKG#LA?XaGq|`*rosajjm!k!c ztC6?aGLkXgz}x43RwX+NB+VpzAxiycQvQzw5QSLv`9&~(yhDR)r727?$nxn4Q{#sz zHQbYwUkWKG7Gv;);FM+~UgO?c&>N>$LadZDGTFkvl8D88kq!7ZD8X3-DGT(3n?E9~ zNU~&QGcWIDxB{r?wW!IDA;6*ZG%Jc%;DlK!rhWq|j0E|==!EP|iKV}^JyQuK3Nd2D z57{0Z`345cMGa;7>f&EXy}pz>yU+vn>U0>ynPQ=ZkarK1kLg%dwTAn4o|}DI8!oxL zxyP$1$=anfRMr_u%}0 zD1r6=O0r>i@hx7L^)dCddIGz|cuSz>i2ZXM;lA-tz@0-n!?9IyT^uOK&K>*F6@m3S z=N-2U4K1;nlZ_dR?``h(NDt@@uTv-z& zkRV8HE&qZc)y}WWjHl-D;c)Xs3dl|gBYC1Kdla-j+cq%9LTxpvef#Ai2zwFIKUn9y z7;^J5to0u@{{>Dh|B3q@otmcqSMB!C-u;h45Bn?<^RMpu=VkwirKJO4{#Uj2Z^8xt zcq0d-GUERr;o{(HUipVVo%tFKt>r<_v7*a;YoQ?i=6AhvQ+MMDQ*EUQ>Gc?MGD zkfy4}pQV&q)zk$fnOmxoHV?jhOjT1CVET`fpww+2{*TI+mmUE4dVuTuduBur_xJV> z7r4;#PyT>p2np9yJ8v`@{>6HWdp~6KZ^4b3{$P5K3pW^DRPI$3m{V)~o-Pc;V+M-c zF)t}Yy97QatXs45Z;fk1@jqUx2ASbbd7 zv3F49Do6`XsEWH?fXg^(WL`p&B`4mX%T~kw3+C@J+pR#sCejoIk8|5T(4#O18yFO=nsxvDhyCf<5AZB zxZE~9`(gQFe1>T~(>$!?*o*H$z)7BE>@U4CvEL#BhEtK8S*i;*_Q7>>qG@WS?4r*O zdHVJZY_aZgf%(B;+1w!b*l&V0cBVB&MWH1(h9u$j{_Lbmt(?k#!KZRmDjcOYETbwZ zcX>IR{H3ykRf?zCHbB$EDNo>wr?gR-bP7@o5*T;Cr6fTdyS zI}5f(qFYxOQq6Uw+`9fI_DUQHGEHbBHqrQfqVa;pAqLCt)HMbporDN%uF2z-MPVU7 zC%Nn;3K79XQ`(>rj99SyLMM^E3Fm&9P_;jWNbI?X-lEWjW%kZC)dUVEXq%w>N0q0y zz>I6(#&TCOcclPLd+;d2Gu>bNxS8H!c}1xCO%`eFeY#A3{Um}EnFtK7ff^oHFGzG^ zIpoIDxfDW{{-{;w+?ETt zOy#Hd)#{jh6r@(TsjB7L@XDpD*#O)M#_sd#k7^HmC@%SoPx$k>r4LLRq~83dPf7NK zJOgc&oy5clS>i);?cjtmNtr*;o)NL}kqGinH*uBwYc_t%=lCvgKh_fa_6&^n$ zdQcU-#6gF$#KD|<$Ag~#1W4aHyg84t@+yZDw^6FK7+U+e^lnJcpxK+}t$&5pmCp~s=^Xkf=O;CQC#;Uz|^6IE6z^erV)UyXZWxZ+2frc460o>jhy2oVCg zh44Qnw#4)%apt!iu?}%70*)gzCo_MjnmI~6~l2M_@X`c-nO~G zG<^q0vomoS?Jo+!yOz(dU7bJ|Hyxx8gS`gH_ysu|7y_irLrNs+eukR^I_a+5 zzZ^2x2pCV3bQjMsSHXE>L#{3P#$t2pu9f(n9CgCyD@rc=!9P{!5f#F zvY$~{3GD=uezsP%*1H5P#t;k%#CJ4Qfu2c1lFaHCgPRQ?j8F2<|3cZyGP|UrWIhDIOczKt!t6*Mk{BS=jK03n% zO^lrP*eH+7Jmr3)iST#ZjmslT>0dl<(9B{ql5>~%hr070fu65Y3K*1IpN@HvXsta3q@W{UJ(!9@mU)u=6I*Y$oj)}keOCGnI!sEv=a14Op)e< z!nPcgpl&7jEKoQ!wJNHU;esStKQMMsU?Fbmm|JLSj`XW^X3k1q8k^u#TtW`FEA)dJ z`D3%+NvgOq2)PdfN<9s@)E=uMFfztrx`oKdQ- z%J)>3N5_pDKjVfAtM!VqPLD`neI}5Wmqb@A=;pLy4_0X_ZuTavGtkSYU<0)&fP<<4 zH@SmiqNS$yK}?Pr?}+f$dP`c^Db~9#cZc0B{@zv#<(83P_BD3xWtgNj&SV&?KFzCm z$Fj*eYv$W-a_VQ!L?gD5sjs4owo%MKM~G~bnU5z4JpSh@OPSA2)tsT>u;vI_*r2@G zyOS|*DB}?E^Ww173n80Xwey4Q7JYwaG@2_6n?dQn$MqcKl8BCR#q9M~3o0~JPlfW) zlbR@34fB?;1Oq^^_{|mf=Bp4b0h_WjVDfYW?y4}m}KA~eSfD8 zRN`AUlZnyvoC8(dp;syB8OszwF zuLYXXmy?oICVX~84F9SR(O`qFr5;7i)Kqz_{IouBrtzrzt=XeC_99T`mJix9sb8{G zveO8$0r`eL*;?P7<$O3(#ZJ6ZY4W?mZ}EO{_+T-~Jodfey498*rkiG2y{ex^6X74O zS|=D+Blu?9EygPRKeck8QI>1n<)UA z?#eLAmW(6d3g?$O2dwr4!~lCT(gY83%ps*LDN<;`)!|?80xBr}SpDnV6<}4dd;ZZz zZ+UmGF+V~*$l*rKlU2Chd1^`TUUwJa&5R-2b9sii}pYq z(TEd6$c2$C$*v z#V$Ni_LDo-36*9~J>5|JO0crWXLJ_gW6XE`RR3btZwQgks8mA@i^;NaA2Wogf`91ICmE-RWk zBg)~25P3y=y3ke5T0TM3+@HvCH56NZD{A(c+S+`epBK^MsI17`mxv_Yg3Ditws;ZnI>HgM{5ZgX4Op znW;NS>K0*N9ErM|{F(nG05sez9PDNoQMFY~r+x>BvU75oW2g4aek))lGeCRe@f^gI@WY z8KiaI!=*})+YTL=NA(0kRz6b|fT$C7s;JrR_VC_Xf$;-L9;B(RDLJ3+9&3bQrulJG zoXNKVGEWYE?Vj0qpC>JC^Y}ix_Gh=f9=&!kU|FrK7aFNF*v#Bv+c7Pc=%`WNN{mX@ zhj5gTZrtvbE8A*`% zK<8B`w0Au)g+*54N%A2wdMxY}wOLO7nvpZN^4UU9iX1(lS?7wcLk#0mcsz)boaOp- zhL(v4u33T4au=X&LxUCSc1u>BZk(kB06?)0_PaJ!4aIc+x%gJhRr9;duTk+DDI|x7 z`n(l-WzU=Pu|>N-fZ&dtQ(SV35+j2z!QXQ%tA+qqZdq{4d`+t93%FR3A(nr}k;}!z=F(2cv~!?t6Q=0<#NfA-_Z3 z72XU-ekJ-!I1tnd)9EvfFAX>uq)2|DXo6RD)>vv(5_rCm26+qI`uNfyoZ<(j(+uPo z@@Bu{m#@A@4{4x=DaiTzvUKezj`fKu0OI@YE{-Wj#TyRl$J5cR?zwECk<;1M8G|M=VH zTf!Q5D{8vmOBQ_pH2Cw7);Ca6>Nx^nf}@-NVj$3XVvR?3u}ThZ2cvy%DK@zPZ-w06 ze&wrSvQw!#0PpZr@&(xqJjGs~8q+VkTBnj#EKkU59<6Dzvy0nZ`M_JQ`o2?Q z<4o?O)u*G@DFtRclCe%F{H!JuN1EH8H5Fi94)*F>=gMP0FOMjUupZOUMj!VH(Iyes zuKW>74$6^`$Qaa!^wX`e(iSFp*kP6t)0(RMY4df3>vX;!dtK=FZ^*sasnl^P)Vnm_ z2h9`6e1X;ym!;H#GU^=&b#rz2|c$WK=n+C{j_-MHT6YjoU(Yjj`)>{j%>pBB(Bsr>=3sJAfJgb=(R z4>nR#0DFnWVrbu7|4iQmQnjO~MOueM&iK-$xz$tp^dFJ!{Ws(A-hx)II_H3mcVn>J z_>~}$YN~6+>17k&#RdT(bCa)poWk^h6*Fx+>h&}2i^52~F1KhIq95+ata`_rSCpp& zB$aFXs#q%9qndrVj{@AWm{57>xVW#N6UF}SzA|EoT1n?KDGT53t{e5zLfKoJ7hg8F ztc}{P6uwN7BGN#f-5Idd=R=)6XK#i_-U#nDsip;=*MidSR>f|ks_CeO%H#X=%Kh6# z%R$peDTUZtW;nL*)|s!+*UFVd!{8rlrEe`5#mq4B<~z64P(Rq&iI}w2+ldL~d&`*0 zk)BAVML}O`B1zgIF}LbWZXO*$h(Ozo5LfcbdPYn&4OYicKKDl`$zx0fb7rqF@7+Z2 zzYC$)8&Fb)`Bc{MUM?eB553dGaSopQh@@zyASP)8Hm^j)i^D2sSW9_|m0ou5_shnV zKa5?AORhZTbJ8wfN*-XhRxds%Dyrq)y;lB4(%<0d#;J3)8`0U{7FBfHRZui4+aoC- zpB?i98D%eUdEKw_xDwv7qUk3hZ|L7{`>-S!;gsA~>6#>Og!n*>Xg#FK?jK(9lXprq zeY+=q!rffOHMY_^e7cmBQYB+dI*091M?^z_LSBy5%^#0G0Qrb!1IFkJ8=`~sVN`4e zffFmE3uiY>#@E#$>xA9GQE%s`M|xEJsI!*d8-K6M_t+r&TKUFT7===g4n^7f;4qYB z1y>Z^T|(%sibT1^DUUHhst*E}rz?%M-f&d9Y7p zpO?L9k?T_X^cP1`j^}NO1K%}TjXIix=l4gDB)hE~BTHu`)pi|Z7L5)QZ4adF)a@Rw zt+ZOPgf8|p+m5_ATRGj~fa^X#SA&PL_VJCyYu>p7o3vUEe!A;iud@pL_L@JP< z5203Sj0GPmk5Q8GV5iP2am|6PI-66-%6dPxs|d}y(L50a;A`DuRM{~A^4Zjhe)xYX zCE8?H;5L#vcw}B-mx|1n5(%!Z?;bH~rG7!@;c?{3E4CFx;G1`ISGQ2^e zSU)#g9KgwcMDxz~e+PBr?d0kA&EOs18`_C%5;(u4N&rdBz1Oo5c*ES;j(7cPndAPp zd&Ws`ihWMRo_oE6woP49Eih2zU`V^tuendvFABrOkjE#ii8b7GuHbrw&k~s@T|hGt z$@Z(0+-)bBH8itjr7B?j@qd)oPi?yy=H{6ovvNO&l!}j<3slottRe z#VL$g#mH%FLr%xdS5{$cJGfpp6fx5wg%XwYPlGounXw(aU1ny37+~ZdKG9$#MJEF; z{81nR$dA2+&-aUa=%6Jq9#+f}$pXZa(^34f{m=pU>TMjSnE|kQ{0F5HU799zY3?xW zF8|#pH53>L<-~*GZzQ^Uy{WmH4P||uL5O34^h@?8OlIAHNBpnFfwRJR3;Oc4@9je# zeE%e+gKt!muEJCeGgs!Uo?dI4Ymj)~z_ReSQTqv)iQuu>%A zDoGnCC#sWJV`?>mTackDLIU+nD_^7daq&y+>yq3TQdoD?`K)RB|4w+uNCPy6OO}`L}%m;FFTA~PYoVd zA;Mq|R^hw-P;xWQ#5nGAV9Gb=zNopTt{r8a6MiuNx@MgX7G?T!8 zEO^Ze;uo;Qm!w!S03-O}2>Ytm{=hse>f4#Q-(UD6`z{%*yPHsm@VJq7Bqh=P(-LIH zxmAu7yhE8=?5+%YFa}PqQMA7CfxpnwCj+XSALmNC3+i9Nuv4y=O$FCVaz`GWNnM;8* zjPytn8ctI93e##VLU(h`$R0_cN?5%?{BoD}_g&8Z!~)x6Y(L?Pd-1Bug~cnUI_m^; z!?Noj6_Iy)sV*0Q^_^{X#MxoboFgd6T(>EFIXc;tEB!iAHKcw#l`-0JuQI?z785t0; zpnRKD2Ed*T;eru9lr;YIY++OBr@FzsIz#r!mTmn#QHN^p0Ba7_gzY8YDpiyo^yRFz zBSo$a*i14hp~YD)}%@q)8tJxt)M!Z**x9Z~sy9Io@8 z$1TO_vUpxC)<{i0({a75>|__`m-b4NT*c_fhaWP$#oCUsuI6qrwc5$XLU+Wf2F3uv zQIdwfiZhmxa9Ny)o%{MJr-b+~`{wlar&Li9z5ra$inRtu(s_{ATF9RkiwKi)C*)36 ziH!gpSQEaf>>8Tk?bEiL&Kw8y%$kTVuTW#*uVrc4_)I2eG&x?EsKIhRaniq!B4AhW zH=e9kw=JJHP-WWf1%rogoM${Lae5eY9U|0?^F%pB>Obfdyxn(m&vt)d>aaXWNc= zn`B0-nHr&nlv}5(Z8#)Y_ykbo7RcWv&4VUSqCw2Hr+}Y78qfTdf-FeDdO{NFElZyHX7lUvjWJSH?Nq4QUe2c(+mxm z;$5%hhGSZi*kmZmETfCRe$^)0yl`CBGXpbs-!xm)Q>46%OZ_>S z@fo5R^tzF_`=yirm8vR?CU?u{!b$G#)=!=!c)cY_SNGtno{TgW?9tn(FmmYXTeB8Q zLrr=0@-^E}^BjUAu(Lx|#`vvIsK!Z}uhwvlkr;m@!^K4XZo@7fHPPXPt|jtp`2pXn zaEqR1gQaxw6?g!Me&H)tG(Y{UP%~YoR`$BR%oPjri-fk>pOk!oHCpW>s2-j6L1il6R2HesAK;f7(eLN4aaO;zM#Qb)R+Hz?Fg%v zfUlLbr%6<*B1K(H+@l!N)iWujk%0s@p&eqGy#kt|Sc?B^B@0w_$8iU))BO0-E7%z2FBep<1fxqSu- z(CCr&^2Xn|X;l@&tW#QegQF9YSekNRz*5&fkoHQ!_ZMu6hn3fXziPx_J`LM`WZO|p zf@U8)m9dtpGc6?lW?LFz^S_r}m8H%Am86i$G|+i~h_;!mDr2~X21$$F0sPkE6lTHR z)nepMQXgMVLdML~6DZ(;+gn9(gv_q2dL?V8&f-qcA&Q`ecF#cnu224u! zfvPEkYD&I!R{4&lO`2XIL3q1;gM?F$in?&1Vz;m9{F3}>&?E!43Z6f#$e-Vg4|jv@ zY@Q?4>6m#2*)yQo0yKpO_*UrU1+7$A147P--zX+7s%4(8PbBtmV=UES)dO)GFXFmt zTAAG0$e^+4OtPyl%A_ib=uVAC1lGAPodLNs=@!VU?fk>5&ngR>=u&NyMZ+IqVYDdU zP&o^3z4!NSTz<-l;5flCj~!gdibQVZaOvQZ_+VtiX3ya7IGnT|h8wR5-K=vWbX~U2 zJzZBU`Y^KQv#A*GAG8oJ8$4W6j?#WtqUUsx6$eiPu$m<7)e$KX=J&Ag|^C<#OqE9d4^SWU4vc8_8~@gnJ1a4 zI|EGO9W7?~!maTuhKj)0g{E<&%hW~|yX?39$kD`cu+NF**FZc6F@aS#xY|yAAi%RN@9cU7I7aNfU zO1`XU+S5%@NfZVr$|2BL%?P+3_|UN+Fxye3%$*;orEiaE9;m_ua~2J~OzH+UC98j| zkNIEbz!Of102Nco6S`7<6rP`EBenB7O?icGwqT+Vp8_P!>`(l z<2HP*>^^;iLAc1+l@6gJlMJK~ABXSpRHkKhpdmJTuczP16w!dj);2OYXNqUW1X%e* z)WPtMRWF7( z_)^4(@dd}#nOZ8zokn3SXpakjsXKf_90)+Yw?CO_2r~<~Gx`#sDe`Qie_;x&8`hZE z$H&s`n4}n{ILwS%GYU8yH?*2bi`y5rcW-vaTjm3^;EK`j{Xk1Xhk*G=n`=NMO{d;1 z|KU%{ZB0b+q-5%@J*lsTf7Q_GI`|X}>p(YJS4;y@J!v;NKlVOd@oU+@9p5-k<4X)Tu^xt`FuJzY-sEQG3g#2@jr2W{$1u0X620 z2LGmG2A;6dHHB5(g@GY$le z$d^-0mwuBOc7e^`fv4`ypSy#sKU!cQ74@^ZiXRkbuhbYoIbRSw66p1cc{t&wJ>&=>WU>l^`6YUgZtoryVsIun2;C9WFu4WClb2+}-xZQQKc{@qByw<*+tl`&FJar_ zAKjeYLmo*?GMT-yTY?5Vz3E0n603vLLFDttmbc0@TX%cbn1D{qW7ylMWqv$Lf|Mw5 zs-}RDHI-NpiE;GrJV}tZ5FiDB?kTF1!kWvnn4)?$ zj}oD=Tg+ke__%>HBz>>@n+^(fDo(tlI>c&5$YGv%Gm6!Zc=(TCf&5SP`X`fmSoan3 z8PJv!^=6AAzy%R8A9)G29l?v z2jick$gk^Y8qcjVbd|e?6p=57zNmVZJR8jfQx!-cBGLgb&A>*BvbwZqSTn847uwIU z-JkBQw8_toxST{D{tx_C&T!G5rwte`X41^z{$n5!u;>K*N%^SP2v0mVAWkc32t7iA=7o!|fgvYt%f58}nNN!Dd#y5^-pjDHdjmPC{Q zX%n)~1y(14?h=mrtq#A?HC(&0oZB0w#z3ngw1GQZ9v&~uw_h_H?I`1pli!yGsu9XL zDe<%7yIgLz8mAOiUJD4^MOk%h!dc*D0W*c#4=C0yNTzUgY zhPCj?VyLYI20C|MixY|M>HW{;-J<$5ti`&tH@P`7DA@B3MsGj2+Zaz8 z8+jga3S1VBqt#qM)Xd4@n~+SejC8MI#oT z5ZXei+C083s=&fyMjM5MzdsMdsLM3GwALl6<0ZS$3Q!CbsG;eJG}XeREiFg%bEs5R z{6eh3RsLb8BDL**kYv;1o<0XEme8Hpzxn3%cFIqybEX(@tcQ1qjH(|{0mxqE)K;&$ zr)!z@Cfe7Ih;)H-ZT+y){r_(|&yA2>MuuN!sofdNYgJ}LboGr3MO(g*Qq)4?71=ip z=N;ehk%pxP(_@HZq1jRbF!IJljyDZ^qqP(`dfm&q_+p4t*Qn%-#S?kzX>xPkw0|~L z{(f{Y`oXJ=EotF~$;3>~wz~gbJ($KpB`?xcNqBP9Rgk(R8`gg<*w5tlPL2D-a|G?i zR=v<^JQ7(ez9yHd*EmvQv`Bwhs7Nq#uN#{wu<149Zp1lW>8$v^`81(Fckeld-(nK3 zTSBlB&LntIW#huCAj~(0GcKzC{S*21D;-`f>ojN2-xRa_fMt&p&+1N80FYRhuEe$p z;C*$Oc6X~=xAyYW<_5jKXBnrPd}TXp1gl;bL~ke@N}4AUnR(nNy8Aj8SxZ*s`M~4t z53GX$oiU7RdC2Ra$VzZUZ2QS!Uh-#0v+-BOBI)Y7W+sg`nD6X%_eCI#r;-|7{+Zj+ zZ+^SEKp{zf@LzT=94yj?afrW4ia<`;4+MOD<$dqTWPYu+g{N?22&r*jk+5ym>u$pN zON6vJU#P-aq=B$Qf{Hg{W2kU{?+80wy%*LaR(jxp)xaRanQZ`dqmc-#qF3_{_ z+#dex!b^zO-Y*Ga;7dh_sLp?gbq+yy%6tTMNzQ*&zeigDVjB;Ql4DQDD}+XR&U!Q` zl?Sa!{dACSF#~6laT>zl{$M(pY`9JGP`t2jTp*4u1;jK^ncB@{8V(wBB@`E)H!#(7 zPcKuGw#EeF+~MXYLwo$UDMigyxhzGN+0W$>T0;Qu-q0L{&b6OjD~8ox3z%{Np9S8* zI%V9PX(+6?j zB-8v(z_EFkDf!k#9Xr`e__9Y&p}+HnxqdbzF;ahQ)0dMvTp(xA<5Za;sjF$wJlV~H z9Wfnb7j{;*g-gDUBiFv@?U!dQiub1bp`@4I=qHn-c zIF(sQ54O5=6wOAd>pZQdrus;5X1GbMdn8$;O$!yV2-onEfq6JP9AK->-QevM#2)Of zMAFY21HRXuVBN4g+64aQkv#gOtTbToO-HEsb08_0QFHZOHLEA8O7N1Jr|g9)R|HgX z%zS@lDsoGuTN*OwDx@Fm*qvY|`fswuGp|dgnyeo-%jn0LxQg213X3xD{umFe$XgYK z?hb|fR4m;~tNBE*51c5}*a{VeL>Uq_Gj#l*zzfmHr3A@hu`g0A;?i3Bbz;Xja0?JY zBuY-PHC8cWH!4-jQG2$|^iTEI3P+ur+qDYaOlnBJ|8=5*g4<>gAafA9ooX>Th-BmS zGpEF|@WUCrfRL0Y$y+(|T&!QC_yNJaUpenm5gycIEvIS#$mz`t` zmdG#(UkmYWP!jhH^%q4VnV@Xh7<*X~!`mVtYBdC5R29w?_~YPQnquxG;C9G|)w0DC ze^0(+swp=hHgI0grBXrXaV=~e>_ft6V+r}KBsmFGKc^~0sRAg1nItJ7{xky-y_pK} z1(I=bnLcWQsL<9%Ug|DvK4~8kq_$x^1EXnf?b{O5)ImzOSsRCe+6Kkps%2YqxSKoQ z_BrZL4>Kz^;`NFHYJw^ts3km?eNy`Aw-Lx}ZpE+r;0G+SdhB=Z+z$XgKcdC`ofX{mV^6!sy^4(df{c|Dj!+nO`m3X$5LiVc1P z9@GgquJQH71Ai}r;-R~)!!>?YaV*`D$u4v7Qq4-YYyI-zFKM|IA6Wn;r*{Ou-#ql6 zOX)mEXHFJfL54OtQ+_oaGCplH{1eJL#ADS8TbC0tQI$AG{T<$IyEni($z4xg5yuyX zN|dz^6OGY!5a1XjgIxh1203SFEoNYysvw>%Azxe>KaIdxGSK|(??3AmIm{CK9F&`T z)Wjb5Kn%E@c3*g-0Z8gyJ}9NeyWIi!Xs0@1^BD?u`m4BisyPd^7a4BYdVUMJ4qM4W zTn9qLwTKA#DJ#`662>W)~c8Fm|zisA&IId#}*FI}o$Clh9j_?{@9g9#NcOIR1ViB!(#j2tI4?aM_ zzr3MMzeh6C&)Ii`GC@d;o$NTZ+Q?^u{n7YbfKg|Lhe^NsK&ZG^>-%%#2x5)=Zx81X zqT_(P1su`M^+r8i07hzw{j4QZvmnI7xC7xz4CJvMVCM2@Rp`V z(z(9(LqcDdS<}yoCp$WF3h!F0$QsQAxrr{{+%%5^2P%Zerr0 zeDt1<8p2HtHB18fOT~(Wg2p`d=g3uoz-SeWqo4Q5+SZ!t z?(E0y@d*-)I)E&|@X0uWSbLyfY;SdK>rr(rDXhy^<}&zDq)zbT^LNN3fru5K^p} zKk%mD8Gsfh7UBPFE&CC%)|L6YwuDT|_T9?W zRbgJFWG?gdZx?o7KYvchp3bYCit~BENluZ|>_xo@awl&1-1?qLT7Ve0%}0eX zvVeD1)3*Mn*?sT4W;WAZ56}S2w%U7RKGhX!Wj8OF=#xD4rW`Uc@a>++Oj*lPX9a~B zhKYR~qLQz@?EdCCL?>jBgB%mn5j;5nk)E7oj^RknZ<;9{5NRYT-B1`VK@2f<43pj@ zVA{%jn*J{#cN*`=SYvaZ9?TA8TrceVg2k3^J~bP>ZWg?9<Y0BHl6b=G24j_Nv6&>BFM*07Re29B0xYyNl5`xIZdectB~t~qViZlk%W(|q?Aq$ z4D11#4S9_o&w5bs(<^3d$Ba0&;nx(AwjuDQg05my!GboivLoe2Rm(V(pjS3Ms1S_K zLP_t)0O;w$<9yhryRX|DYzwj(5ect(w3rU4Rvk`enK(H;Twy#;p)kjwuNS$s(?u;I z@-1&}OYtlsYn<0cy~zu3z+LAMY)62a8z=cdxdCLF6a?SYbTx#h>h0v^F&r_%6+L|6 z3ZBHLIn0s=!O#T64UexF?{gnWws>t?_oPf^2SoTZs5553RJXPFMx#^8bj0~TISa$? zjLCAc+clS>ZqqzZGp3+o1As0)RK>5*@D;j*Gl~C?7jv5K+wR`-NSeJ73wR{`>u3L` z#rPN7zyb8uo^pW}l@4bvf>mKQcf>`Fx)dFP^YTLsh_oHP0f+UE z@g%Rb(dLaFl@bMt=hqzvFO>DRJbGH(e>OwPD8@4NfRQs2=l~AV$-RRN!!(X3RG1%7 zoT%D>=g3K!BGKkurlc&W;)v?c)XhvE0Si$c`AxV6jNeTjdIgu) zU?F|AsfIX$0QiN7k~6hO`~+kyl3ejoOrH8t6cn{*cGSke$%BOWUMw##4d-n*VsjL>(JWzl(^F~S!72XtO9YNuI6_wt1# z^7R19kVj^TfI^*BY1bgo_<)>~0W|E4N1g&ncKRPZPeD z$zbRg%qs{z)$8E-ONRG?LJYA&P-582CD#JMxDlD`F{xGhk8gq{>`E8zwE3Dy)9!Ykuz$tGD(37~udd9-);Co>4uhewN2e-Pv#^aATtrHjnY z;~dwCwEywWjumOmir_Q{Vlm{7XjoyUhr|aDJTojUhu9*VEl~?B7zf?dnrv+t{=9JC zRpaL3o#$;;L=i0p;+plSZuShnv3)Lhv=u&+IQwoU2@wxEu<*(mXEoLGdI0xWCINJU z7Wg)wI4nW~$Xi@7?tJ#YU>3)8-RQ zW2w;ktb4cq5`S#kj56Bc!?|e2iRcE@eM6aVlBT$H*e3i;t3em?%*$_ZCPrnPx?KWf z@K(-BC&QCp#w8bn1I9lZ)>w?T!#3yPK^`LRb z5Dfo|bcr)DJyc^#?ISr=jdpBWL<>x|{F1JPovMs^C0>jzBL6*qe;;u~Yx(*2(<9LM z-p*+$GQ+q9GwC02kU8}~J^^gTp)zW)N9Fsr%h&@BCbrE}|;{gzY_ z?mgBR0M5hojSBlHim^)Q>5^0FRc18LUQpZUI2Z2LYtY?-&RbHagw)@uu6VbUv>NBv zB^SM?i;=%eMdXP8%R&zRDQySbpN6*!+(A_?A!NxB$P`+^88KRRB0s|r4;Lb6aEl}F z$m-BG{snX56zy^(0IOz5T61;m<09Vb78tr#<;IFh%2xFGGo$ypdG1c4on~olm5Z=p zrU?H8sa`7oi1ly)f=$oUQ&bbb(3I28|5)AY*D4}A1XOLI{x9em1RKf#^z;7J%EwC= zfK)JfmEX29uyvh^LcTbAgQ*5CT@8caQVI&T*t*1IS`oTk4eEPBEfnfNc1#cE^k2<_in-YnY@qK~Fg;1a zQVya&xKi1iE!zSQI8Dxtc-drV;EI?=^?t9FmcPv8%4r0LsMkm%%8?Za)%V+bVCt*> zn+!*^=iXzR!>Goah;K*#g<|(02AU^6Pfdq&HiD+fieCDw4ManC_~YU8^O_)8(TWi0 z#aOVvl7$H|5TtHy|B=0~2cV&k(yYb?F|z%bR>uK9BQmSz)Mo~BE(mKJ?7Ie-ffAoJ z`**jz3Y!<+E65BB1u*Gh?Ofq=#GE}n_c2Jw(5TD`7tj(;Y=H*DTU~f<&NR8Yht>s6 zXa-KRzsP=NcylDF9^@bUta_4}I%~~et=H+8p`>gyde-J)i1nMFfMFsQqih9J;FKN!amtIg%^MQBt$XDRPL@Cj$|xD*A&PR z4uT<$BZH#Gm8^#lzEp^)Mz6lx+XpH-N70oh`r@JwQyV*(vtmFn#YuvLn3F(D{Iv@jUS9et>rlC*6 zCBqWC^_z9oawiEG^87skD3M*u!M;F-PfF*8O#iMgk zwMomBv=5DheF(4b=kv94nT5M)We=xQ<|cAaB9dT1Dgz}(wwVt8&hi<$33kxRKoNQ9 zSfG$&$=L?>s!E+tcwwG(Z88;v(bGgV=x>r6WStmL>0kkv{UaNP(eyA$V>VTHPJnC< za*yW&PiVzKVLQv=q`7X~sb8IZ(pL~BWDLqLzAu68w5%~H`g@P)jawr%gFVK_nrZ4X)UEvg*57s zdw|EiA*fLubyu1bo)sGRpc-)1Z9U%gh&7J73?RbSX2&@H_H!aiaW9>G?BdIx z*TXL!%wh~p-QYD(o6#mT&XjCpf7tF}r0l|O(+jkth7DWXAG5|~q4PnC5u_WccCVO0Gjh>>*#Z?5m+=cUJl zknf8%1FQB#)`y!}^$^;Y6~i{SPgA)q%!LH zByHbYIshU4W)$S3!irigHxO1P;KH7bDDM-?3YViA(6++4HR!ZI}A_hEEex#2XzwnI#aJfwY6^h9k-7#%eo2}p!MHy%*ssQ)*3xn`~4QdRa;S)JJN{;B$_1C_Aa zD$oM70EQ^*@WB|_yzOe}N}|^y!cGr@>cE4gf+`|tsOG7eOhm4Wy=i-k0Ncga&xsQ1 zA&RZirxL@=nl~`OYZRdItOXfPc$>IJS9t3^$q4%=O76Xr#?2?a3ptN?KlpO10!VH2 zuPMLA_#Vx>$Yro6R;&uUs_*>Bj`93>1f*v{@a zD&*QNFwxjyku7qpNcAAh4tA0{s(I2?w>1*b(*vdS$nTt|!KDA8N&wbpn>%2b8(aE< zfPpbg=bPzRkDqM{QEo+m%vJp)KwlYh3HU70WXW=~bMwg6u;xRq2KH#UL|ia?gzNX4 zq&;s&pl)+H z{P$|Xww=<6=(E0#sAkFSwdApG7_z3_v3}=(OuS!fAEU{%r9;^1%^Vk1QW=Q6@jjoy z7cGx!4Il(E+CVuoEXQkl?t7NPWQa%NVY@&lIKJno^&;2FZ{hH3rW z4^*cN&v4KJJsFgg+L7+ty`v|e!he>Cj<2~e6CCJ@?m8Xj?qK)JAc~=q@pA%Sz*BM zv~9R8OG@20J#>BuZK|~+Kk!oGbKGP;VrXm)MKmkIJfT>Fl;vH3 z000000000000000DJ)TQt*~EUkWW2g^=w?{1vuLkMtx?1LltRJ{;}&HwCrh)#P;s` zfBqQBDVd-n_+wa6JS_OG=x@^{7NdKe21H6BVauRgGJN6UvYhHtd|IEtYBt30dH-hS zAUd^b{ruWK&YTJ9p~#QIGpFA42lv{RANE;>1YFD|zusZcnT(W2YGlG{7#2ygZ6|Z6 zxJ>7tEaz9v(FkpKQJ;wq)SvImjQ%3(*zJ(ogUY}{i2ZPhxwC1bF26OqKz*O(5#WF_ zP`Tt0SUv_Qn@d3o&`cG7nj^^{#4|U9JaBYAKMQ+KBE>1qk8cynQYpMLdU~#V^V{>I zQOG80-s^VfwLUW8=uq1N&I)Fwh(GfuQkl1F&%YF}XM0&gNalAki?{pF z`JImH$pfCIBBx%jj?Wr7M5ovc@j@xUts_a1m=UsF!7B}A`w%_ZTRgm}k8i_|m4eH( zXw{{xnFmIVLSixcz2F!K-!fEtFqGi9qXC!*tvh#2WXx0{5VbOZ4JCm+CiPNKBJ7Ul zlH$-9S((5L2!_fZ)Wz}ZhSs)!^GSlbk6Yvz5)aK$^Kq=o@oih;dQO5|@{591Gr^?L zw6%Ft?V4|BNj4neOEGDr!94H$ZWUE&PdGx*Q0;LicqVRkc4(;9&ZJAXMF+LT*J{dD zxoJ)&zNTukY`5fiHOO}JI0LZPN^Tb+f+n&4bI`VtV3Bzb6#4wg_;rORg;rKfw9wIE zinOB^G;!1)Prgl%1MJN#6m(Az#P2f_$5u#Gt9tzBYgpk{H=^#M0iyDQ|{*KNz3+|9!H(kc6=#) zWUY4hvd~?Eq7u!+Q!ewQ{AIZmr!HE^2!!RO{*Y6IeyM-_yE^Ma6ZNxu3_EE>Hv z#FrKsH9_y)tUp3Uzr#%Hw!b$h-z3F5hR}LPT%%0c!C?Vr$4_O35$WBM>P2{=kbHD6 z={1-)zaO48A{pJ_000LSi*ljt!|K5lN5P`)X=u57XRca=F|sf}tYnE|5=CYFM5C4+ZGAw4_!$ zSv5GUJeo=6#VGZAQ`HxHmnM>uCP|D_BJF1o(kk>3CFh4_=AB;qtLbq!v2*V~^@Ks< zP_or&zW<1zNyTY&#)=GU6FL3*&+3@5*r@MIq_qjl3SV^qdI)_E&DlJsP>RgSi!VNR ze5pv>9P;SfT+HxQx!nCOAYC9yq+*uQ{h&imkOz{By`k9V|7)la&Vd|@Pc*4;9|t9Q zp(Ugbj>|$S82gD7|J)>9WoS5^0xo@d>gC4&t>@-VNE|L} zT91dxaD-Bw1*tV=9X~mbdBL4aJjiJ&FeH_PGqt%}pV?OJI{U8Veleg*&#UfDK^{nVF5 zjQ-Xk@dE|=f>0v?Y3s2UjYwjx zM4|EfV*YYpDVM3&;?K|#>HDlsHUuMJA1eP-sW7+=I>ugO?pn0ci0#jsu%G{WjBGc$8Zz)f9u0jt;00H~U&Q)3H z5#d0jx=_9J$m}5W}(w9 z$&`zhHfOw(HTk`AY%?q*&<|L8`%fMP+)Ba=>;3k7*q;qiixD*?p84 z$zD++QCtC-iCNLuwQlZ)rLw*N^=AHE@Q-TvtS7(0ek%b5=fe>LBD>8IcmF|51GD1B@n~2UHw_Lr^CJd}PNC6Kc%~*=b)9?HamEqskuOPq`Yy9T=xKkJTTaz+ zDa7~ZuF(+Ty-c}xk`4onu2K4af0Dfz#SXNaJ>$|wu$|@KrK^iD17rp;PK0d`1*ZiG0{o(aSS~@`=NUqHa5Noui@R{4UEve7ZNfPiDpFqe*2}@%9SODAUeJT zv6?}eTu27x5$E=S0&i)pAWXfcdS*@2V4-B5G=z(5&%li$y-{dk;-~m0{wk2yk#^r+ zB@(4sr6ho@9Jojp!>A9`>lGl;lWA;ST68HA)fn{mP!3vLKX%m+B2)13*SaV^`ni#3 z%Q@k?08}M`3LJG|=RLu|J0uZ-uEIR=CO|VT6fy6J7%Ec~9EC0N9)ua&QBu+TKBoHm z`+F~E<~i^k8|^YQNE?|2Oe?njb*VcI=7S7Tc+At>(T)}nLrIznekO+(f5F2MbWEp_0d9O4y>uow`Aa ztP3?&AT>|Ocai&9Qn=BR6Uc{fh@j2WTTTG~!aGBKiwAajY1O5``_)$0z9-cWo~%M# zecR5r{$c+1VnRRmyT!g zDWPR_Gr)45RGP6zQj6+E9lvE@I(pN?`~W%m8(X1&@T6OyJD25)LUx^Y(agfR-Sw`u zU96kgxJMHBbE!Gj-2jY!ui%q#h;53Th8>$w(B)ee^?*bnor4?QdkIli$ z$xrjVX^V3X<8>{9?qT4`D`T(Lcva8W9cRM9?C9Lp4cSuEF!mPQWju=k4n+?iOhY(A z%P;PV@H|q5bHQ&~diI^SVsYvfvowH?BPlG=6M9FZTG!af9&j4jqs&+4{$SvCA)AjtvZ@;{mXKT!((+n4$@79L_SLY||i>zqr zMIDGz))-Z@9?i$E^X1f-Br@ z1q(616y0Z!3Q^irzpV%+tD8AULvQu$vOk$fTSZa0oyhqc7c%ed=RmBW4lpaHSpQPW zVh1gx;~)M4=hw&M_A%3yFYt6LDk6WM z59c^786ygJ`P=I-{;T=29{hCW`|=luTh3m7Zh6Drp=-_NJnb1^e_3doMYd7 zQNPMOqz`E3elGm*OGcu;x>=yLvAwd%8KKYh zY9V2=(~nU+XsrocIB3m!pRYq<(HPn{)FbNXv4CwFSDn@&tN89!4yNxGz_m+$QW3zP6BJ%I!7+Aw|sShr*u__FwNLM_7 zV8iRr2r4zx$;^()ofR&6M_YFMWJ)OtoAVoj@Vp~lP?0_K@_9KsXK2og*WicAfV@5b z6$RB|mI>KuD|PIqh{(5fdA#U^pshy<0%vk4xQggarL#?zz<*7T34)@)_t%NonxC3F z>B$Yce6ZfJZiAbPYgB@jTUk&_gcZ&O^QdrX9|r&)b7FY7wEZ4e;)?uT{KmJ2L#^s~Y-K0-Ay^#&<7D9R~*u2^1Z!;&YH=3p`qi|qF&Kq@1!UDn7g{6)Lc z5}=zqXN2)FIYzji))bLRG%b#9r>qG6fhJ*c6k7sdQ(58~Xjbh1npJ39pCD^Rpe38l z3ohA>keb*<90BmqkT=Cn#s0zxcCO46H6l zUUZ2M)I>23yIOKizOeeiB*+H!so%0DH3$)xtzNkKN?5AAY%*d-+olPesqZwLycjf1 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 z%@6tLjLhLndE^WOT}*@$zewW$5C8xG00000000000000000000000000000000000 E0EGjnvH$=8 literal 0 HcmV?d00001 diff --git a/mobile/src/main/res/drawable/launch_list_preview.webp b/mobile/src/main/res/drawable/launch_list_preview.webp new file mode 100644 index 0000000000000000000000000000000000000000..707aa3d92d8a3f489778908881d19833df63e786 GIT binary patch literal 86986 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 JFdfCua_Rg0mtX)9%(R%H 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

384<%>9F<<-j#fsnC` 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

mmd4 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 z000000E9pQ0000000000002u`S*{@NB2|pWdld!i10TVp5Y_+y000000000000000 F007<08=C+C literal 0 HcmV?d00001 diff --git a/mobile/src/main/res/drawable/launch_timer_preview.webp b/mobile/src/main/res/drawable/launch_timer_preview.webp new file mode 100644 index 0000000000000000000000000000000000000000..149e58751336c0ccda91c7da3f9cba424855ade6 GIT binary patch literal 18348 zcmd41V~{T0vM$;-XWO=|*|zPT-96jZY}>YN+qP}nw*8)Ot-a6M_lvXlI`{s&6;+Xu zBSsA5$mhwd%2JXP6Dt%40#X+hQczRi)PMm30z&%h;RgrG0Ra+}QIL@QO9Mt^1Rx^| z5s^wxV`cUnVRZ^3;LQP`p#VF-E1YcKa{zDu*L&ye5RgFw^w%7Otbffnn**E$Of3MO z3&Mv57bKX6B=JjE4hpDWOS>mmFU*JFlk#i#szmX%=bqpKQ0%kf!}%q_OZ7Q&XZv3B zt=r2V<_+iX_6=~u zaldl~IOd=5Nd!cE001$!ws$qhJKOw?K5+oezZxjUab9Rv4PPOzV@?2zDu|z;w*-$9 zvl(V)J$?XjA30V*cF;#q3G0DfKrergH~4q1kNEfRTB1+TSC?I%vy~^kLyug7K7L;x zv`_qRziHrC;CtXtl-HTv6ClW2#67)XerT`a9-vRMho9e6uj==(uLQTY2Rj=+l09Yj zzTV*grk7#p9%umnr^r{sSKBAxE@rkT=bH(j4j4H$Jq2WXv-oHN^1k&BK{>uu&W&#Y zMF6?)uCJF*#FvJsP*e!KZ=?wtm`Er5L&1uxbMA z_yGRq|DyOzd9l6Qx$)@%0014Y9UmiaId?n9KIec$z+d)#Ah-rx@{jn$0Or14{^|jk zwLK)5@fq>41JD6zJ{bUj4}NFw-W~_9aDHu{!*8F^^xCfKUjTbk&wno%GP%cpe+z_Y z%J7dOT~LL*f#4Z40tkgGiwO>)oDv5<{SfL?ePW50l@ag3{#{q(>3l{QqM@w&=QfwG zed9;f+(1L(jaoDJQ&EA)WY|49rFvv=T~UmbMAq=Uj~fFtcszj^3% zeE*LETR7~(LQF`RtUHS@9JBVH=C~EJyu0%9=2H0V$Al8fR1sEgk7+$L(P#@Yt(O-T zbmvrs*)1}JM2b!L#WyEcps>Hao~~tWT=0;#OOlWg(!h2wbAp#1u>%+s5-�BcAx{ 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 kDi{RKq_+NiH2?qr00000000000000000000000000IoKzCjbBd literal 0 HcmV?d00001 diff --git a/mobile/src/main/res/drawable/rounded_top.xml b/mobile/src/main/res/drawable/rounded_top.xml new file mode 100644 index 000000000..85a996522 --- /dev/null +++ b/mobile/src/main/res/drawable/rounded_top.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/mobile/src/main/res/drawable/word_timer_preview.png b/mobile/src/main/res/drawable/word_timer_preview.png deleted file mode 100755 index 73f6704058a998ee5711927f03dc8f3696f3079d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13046 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 diff --git a/mobile/src/main/res/layout/activity_launch_detail.xml b/mobile/src/main/res/layout/activity_launch_detail.xml index ee6974e4b..7534a7389 100644 --- a/mobile/src/main/res/layout/activity_launch_detail.xml +++ b/mobile/src/main/res/layout/activity_launch_detail.xml @@ -108,25 +108,32 @@ android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - + android:layout_height="match_parent"> + + + + + + - + app:popupTheme="@style/AppTheme.PopupOverlay" /> + android:layout_marginTop="@dimen/material_baseline_grid_1x"> + android:layout_margin="@dimen/material_baseline_grid_0.5x" + android:text="Become a Supporter" /> + ​ diff --git a/mobile/src/main/res/layout/launch_list_item.xml b/mobile/src/main/res/layout/launch_list_item.xml index 95367af58..63ad1985b 100644 --- a/mobile/src/main/res/layout/launch_list_item.xml +++ b/mobile/src/main/res/layout/launch_list_item.xml @@ -1,6 +1,8 @@ - @@ -19,11 +21,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mobile/src/main/res/layout/view_custom_button.xml b/mobile/src/main/res/layout/view_custom_button.xml deleted file mode 100644 index 8f57b74a9..000000000 --- a/mobile/src/main/res/layout/view_custom_button.xml +++ /dev/null @@ -1,14 +0,0 @@ - - \ No newline at end of file diff --git a/mobile/src/main/res/layout/whats_new.xml b/mobile/src/main/res/layout/whats_new.xml deleted file mode 100644 index 24a033316..000000000 --- a/mobile/src/main/res/layout/whats_new.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/mobile/src/main/res/layout/whats_new_night.xml b/mobile/src/main/res/layout/whats_new_night.xml deleted file mode 100644 index 426474e21..000000000 --- a/mobile/src/main/res/layout/whats_new_night.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - diff --git a/mobile/src/main/res/layout/widget_become_supporter.xml b/mobile/src/main/res/layout/widget_become_supporter.xml new file mode 100644 index 000000000..ff054d5b3 --- /dev/null +++ b/mobile/src/main/res/layout/widget_become_supporter.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + ' + + + diff --git a/mobile/src/main/res/layout/widget_config_activity.xml b/mobile/src/main/res/layout/widget_config_activity.xml deleted file mode 100644 index 2e0d6b7af..000000000 --- a/mobile/src/main/res/layout/widget_config_activity.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mobile/src/main/res/layout/widget_launch_card.xml b/mobile/src/main/res/layout/widget_launch_card.xml deleted file mode 100644 index 3509b8411..000000000 --- a/mobile/src/main/res/layout/widget_launch_card.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/mobile/src/main/res/layout/widget_launch_card_compact_dark.xml b/mobile/src/main/res/layout/widget_launch_card_compact_dark.xml index 96b4652f0..0c134b641 100644 --- a/mobile/src/main/res/layout/widget_launch_card_compact_dark.xml +++ b/mobile/src/main/res/layout/widget_launch_card_compact_dark.xml @@ -21,18 +21,16 @@ android:id="@+id/TitleCard" android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="8dp" android:orientation="horizontal"> + android:padding="@dimen/material_baseline_grid_0.5x" + android:layout_marginEnd="@dimen/material_baseline_grid_1x" + android:src="@drawable/ic_unknown_white" /> + + @@ -78,7 +88,7 @@ android:maxLines="1" android:padding="2dp" android:singleLine="false" - android:textSize="18sp" + android:textSize="16sp" android:textColor="@color/dark_theme_secondary_text_color" android:text="Unknown Launch Date" /> diff --git a/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml b/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml index de28bd9f9..624852813 100644 --- a/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml +++ b/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml @@ -20,17 +20,16 @@ android:id="@+id/TitleCard" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="horizontal" - android:padding="8dp"> + android:orientation="horizontal"> + + + android:orientation="horizontal"> + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mobile/src/main/res/layout/widget_launch_timer_dark.xml b/mobile/src/main/res/layout/widget_launch_timer_dark.xml deleted file mode 100644 index e243f587d..000000000 --- a/mobile/src/main/res/layout/widget_launch_timer_dark.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mobile/src/main/res/layout/widget_launch_timer_large_dark.xml b/mobile/src/main/res/layout/widget_launch_timer_large_dark.xml deleted file mode 100644 index 4924c5722..000000000 --- a/mobile/src/main/res/layout/widget_launch_timer_large_dark.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mobile/src/main/res/layout/widget_launch_timer_small_dark.xml b/mobile/src/main/res/layout/widget_launch_timer_small_dark.xml deleted file mode 100644 index 183338f00..000000000 --- a/mobile/src/main/res/layout/widget_launch_timer_small_dark.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mobile/src/main/res/menu/menu_support.xml b/mobile/src/main/res/menu/menu_support.xml index 607b44b8d..d775f54d3 100644 --- a/mobile/src/main/res/menu/menu_support.xml +++ b/mobile/src/main/res/menu/menu_support.xml @@ -3,8 +3,14 @@ xmlns:tools="http://schemas.android.com/tools" tools:context=".ui.supporter.SupporterActivity"> + + diff --git a/mobile/src/main/res/values-night/themes.xml b/mobile/src/main/res/values-night/themes.xml index b5f18253f..fba328c0e 100644 --- a/mobile/src/main/res/values-night/themes.xml +++ b/mobile/src/main/res/values-night/themes.xml @@ -6,6 +6,7 @@ @color/darkPrimary_dark @color/darkAccent @color/darkPrimary + @color/darkPrimary @color/darkIcons @color/cardview_dark_background @@ -40,6 +41,14 @@ true + + + + + + diff --git a/mobile/src/main/res/xml-v17/widget_launch_card_compact_info.xml b/mobile/src/main/res/xml-v17/widget_launch_card_compact_info.xml index 4b3684da3..88bb8f3bb 100644 --- a/mobile/src/main/res/xml-v17/widget_launch_card_compact_info.xml +++ b/mobile/src/main/res/xml-v17/widget_launch_card_compact_info.xml @@ -6,8 +6,8 @@ android:minWidth="250dp" android:minHeight="110dp" android:updatePeriodMillis="1800000" - android:initialLayout="@layout/widget_launch_card_compact_dark" + android:initialLayout="@layout/widget_launch_card_compact_large_dark" android:resizeMode="vertical|horizontal" android:widgetCategory="home_screen" - android:previewImage="@drawable/launch_card_compact_preview"> + android:previewImage="@drawable/launch_card_preview"> \ No newline at end of file diff --git a/mobile/src/main/res/xml-v17/widget_launch_word_timer_info.xml b/mobile/src/main/res/xml-v17/widget_launch_word_timer_info.xml index 8532ba549..9762c90e4 100644 --- a/mobile/src/main/res/xml-v17/widget_launch_word_timer_info.xml +++ b/mobile/src/main/res/xml-v17/widget_launch_word_timer_info.xml @@ -6,8 +6,8 @@ android:minWidth="250dp" android:minHeight="110dp" android:updatePeriodMillis="1800000" - android:initialLayout="@layout/widget_launch_word_timer_dark" + android:initialLayout="@layout/widget_launch_word_timer_large_dark" android:resizeMode="vertical|horizontal" android:widgetCategory="home_screen" - android:previewImage="@drawable/word_timer_preview"> + android:previewImage="@drawable/launch_timer_preview"> \ No newline at end of file diff --git a/mobile/src/main/res/xml/appearance_preferences.xml b/mobile/src/main/res/xml/appearance_preferences.xml index 9456c6de8..f3acccefe 100644 --- a/mobile/src/main/res/xml/appearance_preferences.xml +++ b/mobile/src/main/res/xml/appearance_preferences.xml @@ -65,6 +65,24 @@ app:cpv_showColorShades="false" app:cpv_previewSize="large" app:cpv_showAlphaSlider="true"/> + + \ No newline at end of file diff --git a/mobile/src/main/res/xml-v17/widget_launch_timer_info.xml b/mobile/src/main/res/xml/widget_launch_list_info.xml similarity index 53% rename from mobile/src/main/res/xml-v17/widget_launch_timer_info.xml rename to mobile/src/main/res/xml/widget_launch_list_info.xml index ec35365ec..54780cca8 100644 --- a/mobile/src/main/res/xml-v17/widget_launch_timer_info.xml +++ b/mobile/src/main/res/xml/widget_launch_list_info.xml @@ -1,13 +1,13 @@ + android:previewImage="@drawable/launch_list_preview"> \ No newline at end of file diff --git a/mobile/src/main/res/xml/widget_launch_timer_info.xml b/mobile/src/main/res/xml/widget_launch_timer_info.xml deleted file mode 100644 index 5d919455f..000000000 --- a/mobile/src/main/res/xml/widget_launch_timer_info.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - \ No newline at end of file diff --git a/mobile/src/main/res/xml/widget_launch_word_timer_info.xml b/mobile/src/main/res/xml/widget_launch_word_timer_info.xml index 8532ba549..9762c90e4 100644 --- a/mobile/src/main/res/xml/widget_launch_word_timer_info.xml +++ b/mobile/src/main/res/xml/widget_launch_word_timer_info.xml @@ -6,8 +6,8 @@ android:minWidth="250dp" android:minHeight="110dp" android:updatePeriodMillis="1800000" - android:initialLayout="@layout/widget_launch_word_timer_dark" + android:initialLayout="@layout/widget_launch_word_timer_large_dark" android:resizeMode="vertical|horizontal" android:widgetCategory="home_screen" - android:previewImage="@drawable/word_timer_preview"> + android:previewImage="@drawable/launch_timer_preview"> \ No newline at end of file diff --git a/mobile/version.properties b/mobile/version.properties index c24784b2d..0822d1354 100644 --- a/mobile/version.properties +++ b/mobile/version.properties @@ -1,2 +1,2 @@ -#Thu Dec 21 12:31:31 EST 2017 -AI_VERSION_CODE=1020 +#Sat Dec 30 12:12:53 EST 2017 +AI_VERSION_CODE=1070 diff --git a/wear/version.properties b/wear/version.properties index e00ca3948..d88b8c4db 100644 --- a/wear/version.properties +++ b/wear/version.properties @@ -1,2 +1,2 @@ -#Thu Dec 21 16:02:25 EST 2017 -AI_VERSION_CODE=6 +#Sat Dec 30 12:12:53 EST 2017 +AI_VERSION_CODE=56 From 24f523c3bd5cac13bd5db1947265a34cd89f63d4 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Sun, 31 Dec 2017 13:36:19 -0500 Subject: [PATCH 23/41] Color palette changes - 2.0.0 Beta --- .gitignore | 1 + mobile/src/main/assets/CHANGELOG.md | 13 ++++++---- .../spacelaunchnow/common/BaseActivity.java | 16 ------------ .../spacelaunchnow/ui/main/MainActivity.java | 6 ++--- .../widget/launchlist/LaunchListManager.java | 13 ++++++++-- .../src/main/res/drawable/rounded_bottom.xml | 6 +++++ .../res/layout/activity_launch_detail.xml | 2 +- mobile/src/main/res/layout/app_bar_main.xml | 5 ++-- .../src/main/res/layout/content_card_item.xml | 11 +++----- .../widget_launch_card_compact_dark.xml | 5 ++-- .../widget_launch_card_compact_large_dark.xml | 4 +-- .../main/res/layout/widget_launch_list.xml | 25 ++++++++++++------- mobile/src/main/res/values/colors.xml | 10 ++++---- 13 files changed, 63 insertions(+), 54 deletions(-) create mode 100644 mobile/src/main/res/drawable/rounded_bottom.xml diff --git a/.gitignore b/.gitignore index 3a6c0ad80..875d4f852 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ projectFilesBackup/.idea/workspace.xml *.apk keystore.properties +mobile/keystore.properties diff --git a/mobile/src/main/assets/CHANGELOG.md b/mobile/src/main/assets/CHANGELOG.md index 025b85655..f51d8c8d9 100644 --- a/mobile/src/main/assets/CHANGELOG.md +++ b/mobile/src/main/assets/CHANGELOG.md @@ -3,16 +3,19 @@ A space launch tracker for Android using data from the Launch Library API. [View the latest releases here.](https://github.com/ItsCalebJones/SpaceLaunchNow-Android/releases) ## Changelog -#### Updated 11-25-2017 +#### Updated 12-31-2017 --- ### Version 2.0.0 (Latest) #### Overview -Color. Colors everywhere. Widgets. +Took a lot of time to refine the current UI design, adding color and tightening up keylines wherever I could. Also added a new widget for Supporters - a list of upcoming launches. #### Changelog -* blah -* blah -* blah +* Added a new Launch List widget for Supporters. +* Added links to Discord, Twitter, Facebook, and Website. +* Improved feedback mechanism - now have the option to email from the app. +* Improved general UI with colors and better layouts. +* Refined layouts and function of existing widgets. +* Fixed a bug with not displaying the time in 24-hour mode on Android wear. --- ### Version 1.8.2 (Beta) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/common/BaseActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/common/BaseActivity.java index ea7b73438..40f3e97b5 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/common/BaseActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/common/BaseActivity.java @@ -28,22 +28,6 @@ public BaseActivity (String screenName){ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); realm = Realm.getDefaultInstance(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = getTheme(); - theme.resolveAttribute(R.attr.recentBarColor, typedValue, true); - int color = typedValue.data; - - Bitmap bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round); - ActivityManager.TaskDescription td = new ActivityManager.TaskDescription(null, bm, color); - - setTaskDescription(td); - if (bm != null) { - bm.recycle(); - } - } } @Override diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java index 258fa9440..63438d7e4 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java @@ -235,14 +235,14 @@ public void onAdLoaded() { .withIcon(CommunityMaterial.Icon.cmd_discord) .withLevel(2) .withName("Discord") - .withDescription("Hop on Discord during launches!") + .withDescription("Join the Community") .withIdentifier(R.id.menu_discord) .withSelectable(false), new SecondaryDrawerItem() .withIcon(CommunityMaterial.Icon.cmd_twitter) .withLevel(2) .withName("Twitter") - .withDescription("Connect on Twitter!") + .withDescription("Connect on Twitter") .withIdentifier(R.id.menu_twitter) .withSelectable(false), new SecondaryDrawerItem() @@ -256,7 +256,7 @@ public void onAdLoaded() { .withIcon(CommunityMaterial.Icon.cmd_web) .withLevel(2) .withName("On the Web") - .withDescription("Bookmark spacelaunchnow.me") + .withDescription("Space Launch Now - Official Site") .withIdentifier(R.id.menu_website) .withSelectable(false) ), diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java index 5ef3cd0c9..7e7c68f2f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java @@ -13,6 +13,7 @@ import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.ui.main.MainActivity; +import me.calebjones.spacelaunchnow.ui.supporter.SupporterActivity; import me.calebjones.spacelaunchnow.ui.supporter.SupporterHelper; import me.calebjones.spacelaunchnow.utils.UniqueIdentifier; import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; @@ -55,7 +56,7 @@ private void buildSupporterWidget(int appWidgetId) { int widgetIconsColor = sharedPref.getInt("widget_icon_color", colorWhite); if (sharedPref.getBoolean("widget_theme_round_corner", true)) { - remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded); + remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded_bottom); remoteViews.setImageViewResource(R.id.title_background, R.drawable.rounded_top); } else { remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.squared); @@ -70,6 +71,7 @@ private void buildSupporterWidget(int appWidgetId) { remoteViews.setInt(R.id.bgcolor, "setColorFilter", Color.rgb(red,green,blue)); remoteViews.setInt(R.id.bgcolor, "setAlpha", widgetAlpha); + widgetAlpha = Color.alpha(widgetAccentColor); red = Color.red(widgetAccentColor); green = Color.green(widgetAccentColor); blue = Color.blue(widgetAccentColor); @@ -92,6 +94,12 @@ private void buildSupporterWidget(int appWidgetId) { remoteViews.setOnClickPendingIntent(R.id.title, actionPendingIntent); + Intent supportIntent = new Intent(context, SupporterActivity.class); + supportIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + PendingIntent supportPendingIntent = PendingIntent.getActivity(context, 0, supportIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + remoteViews.setOnClickPendingIntent(R.id.supporter_message, supportPendingIntent); + appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } @@ -114,7 +122,7 @@ private void buildWidget(int appWidgetId) { int widgetIconsColor = sharedPref.getInt("widget_icon_color", colorWhite); if (sharedPref.getBoolean("widget_theme_round_corner", true)) { - remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded); + remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded_bottom); remoteViews.setImageViewResource(R.id.title_background, R.drawable.rounded_top); } else { remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.squared); @@ -129,6 +137,7 @@ private void buildWidget(int appWidgetId) { remoteViews.setInt(R.id.bgcolor, "setColorFilter", Color.rgb(red,green,blue)); remoteViews.setInt(R.id.bgcolor, "setAlpha", widgetAlpha); + widgetAlpha = Color.alpha(widgetAccentColor); red = Color.red(widgetAccentColor); green = Color.green(widgetAccentColor); blue = Color.blue(widgetAccentColor); diff --git a/mobile/src/main/res/drawable/rounded_bottom.xml b/mobile/src/main/res/drawable/rounded_bottom.xml new file mode 100644 index 000000000..a54f6910b --- /dev/null +++ b/mobile/src/main/res/drawable/rounded_bottom.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/mobile/src/main/res/layout/activity_launch_detail.xml b/mobile/src/main/res/layout/activity_launch_detail.xml index 7534a7389..c2326d67c 100644 --- a/mobile/src/main/res/layout/activity_launch_detail.xml +++ b/mobile/src/main/res/layout/activity_launch_detail.xml @@ -139,7 +139,7 @@ android:id="@+id/fab_share" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginBottom="58dp" + android:layout_marginBottom="@dimen/material_baseline_grid_1x" android:layout_marginEnd="@dimen/material_baseline_grid_1x" android:src="@drawable/ic_menu_share_white" app:layout_anchor="@id/detail_viewpager" diff --git a/mobile/src/main/res/layout/app_bar_main.xml b/mobile/src/main/res/layout/app_bar_main.xml index 6a6c51602..d6000a2b6 100644 --- a/mobile/src/main/res/layout/app_bar_main.xml +++ b/mobile/src/main/res/layout/app_bar_main.xml @@ -11,14 +11,15 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay" - app:elevation="0dp"> + app:elevation="8dp"> + app:popupTheme="@style/AppTheme.PopupOverlay" + app:elevation="8dp"/> diff --git a/mobile/src/main/res/layout/content_card_item.xml b/mobile/src/main/res/layout/content_card_item.xml index 9354c9e73..c7b1c0d58 100644 --- a/mobile/src/main/res/layout/content_card_item.xml +++ b/mobile/src/main/res/layout/content_card_item.xml @@ -254,7 +254,7 @@ android:layout_alignParentLeft="false" android:layout_alignParentTop="false" android:layout_marginBottom="2dp" - android:layout_marginLeft="20dp" + android:layout_marginStart="@dimen/material_baseline_grid_1x" android:layout_marginTop="2dp" android:gravity="center" android:text="Watch Live" @@ -270,10 +270,8 @@ android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_gravity="right" - android:layout_marginRight="10dp" - android:padding="10dp" - android:text="Share" - android:textColor="?android:textColorHighlight" /> + android:layout_marginRight="@dimen/material_baseline_grid_1x" + android:text="Share" /> + android:text="Explore" /> diff --git a/mobile/src/main/res/layout/widget_launch_card_compact_dark.xml b/mobile/src/main/res/layout/widget_launch_card_compact_dark.xml index 0c134b641..5ff3dda95 100644 --- a/mobile/src/main/res/layout/widget_launch_card_compact_dark.xml +++ b/mobile/src/main/res/layout/widget_launch_card_compact_dark.xml @@ -29,13 +29,14 @@ android:layout_height="100dp" android:layout_gravity="center" android:padding="@dimen/material_baseline_grid_0.5x" - android:layout_marginEnd="@dimen/material_baseline_grid_1x" + android:layout_marginStart="@dimen/material_baseline_grid_1x" + android:layout_marginEnd="@dimen/material_baseline_grid_0.5x" android:src="@drawable/ic_unknown_white" /> diff --git a/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml b/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml index 624852813..14ad44bc0 100644 --- a/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml +++ b/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml @@ -29,14 +29,14 @@ android:layout_gravity="center" android:padding="@dimen/material_baseline_grid_0.5x" android:layout_marginStart="@dimen/material_baseline_grid_1x" - android:layout_marginEnd="@dimen/material_baseline_grid_1x" + android:layout_marginEnd="@dimen/material_baseline_grid_0.5x" android:src="@drawable/ic_unknown_white" /> - - - + android:layout_height="match_parent"> + + + + + + \ No newline at end of file diff --git a/mobile/src/main/res/values/colors.xml b/mobile/src/main/res/values/colors.xml index 801a3e928..0472bf945 100644 --- a/mobile/src/main/res/values/colors.xml +++ b/mobile/src/main/res/values/colors.xml @@ -1,11 +1,11 @@ - #42a5f5 - #1E88E5 - #1e88e5 - #2962ff + #2196F3 + #1976D2 + #1976D2 + #BBDEFB #42a5f5 - #ef5350 + #FF5252 #05A8AA #f44336 #212121 From f0690e26580281dfa80f970ca44d7c7d0377533a Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Sun, 31 Dec 2017 13:56:37 -0500 Subject: [PATCH 24/41] Beta --- build.gradle | 2 +- mobile/build.gradle | 2 +- mobile/version.properties | 4 ++-- wear/version.properties | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 057e377f9..af2e5d0f3 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { google() } dependencies { - classpath "io.realm:realm-gradle-plugin:4.2.0" + classpath "io.realm:realm-gradle-plugin:4.3.1" classpath 'com.android.tools.build:gradle:3.0.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/mobile/build.gradle b/mobile/build.gradle index 54fe83652..3c1f96080 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -81,7 +81,7 @@ android { // enable true // reset() // include 'x86_64', 'x86', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips' -// universalApk false +// universalApk true // } // } diff --git a/mobile/version.properties b/mobile/version.properties index 0822d1354..cdb17505b 100644 --- a/mobile/version.properties +++ b/mobile/version.properties @@ -1,2 +1,2 @@ -#Sat Dec 30 12:12:53 EST 2017 -AI_VERSION_CODE=1070 +#Sun Dec 31 13:54:20 EST 2017 +AI_VERSION_CODE=1075 diff --git a/wear/version.properties b/wear/version.properties index d88b8c4db..d8bdb29e8 100644 --- a/wear/version.properties +++ b/wear/version.properties @@ -1,2 +1,2 @@ -#Sat Dec 30 12:12:53 EST 2017 -AI_VERSION_CODE=56 +#Sun Dec 31 13:54:20 EST 2017 +AI_VERSION_CODE=61 From d637a370e3adf1fd0860121360845d3e570ccd9c Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Tue, 2 Jan 2018 02:08:19 -0500 Subject: [PATCH 25/41] 2.0.0 Beta --- build.gradle | 4 +- .../content/database/ListPreferences.java | 32 ------------ .../activity/LaunchDetailActivity.java | 3 +- .../ui/main/launches/ListAdapter.java | 52 ++++++------------- .../launches/PreviousLaunchesFragment.java | 3 +- .../ui/main/missions/MissionAdapter.java | 2 +- .../ui/main/next/CardAdapter.java | 17 +++--- .../ui/settings/AboutActivity.java | 2 +- .../fragments/AppearanceFragment.java | 7 ++- .../spacelaunchnow/utils/Utils.java | 6 +++ .../launchcard/LaunchCardCompactManager.java | 13 ++++- .../widget/launchlist/LaunchListFactory.java | 7 +-- .../widget/launchlist/LaunchListManager.java | 7 +++ .../wordtimer/LaunchWordTimerManager.java | 25 ++++----- .../res/layout-w500dp/content_card_item.xml | 39 ++++---------- .../layout-w500dp/detail_launch_summary.xml | 28 +++++----- mobile/src/main/res/layout/app_bar_main.xml | 4 +- .../src/main/res/layout/content_card_item.xml | 46 +++++----------- .../main/res/layout/detail_launch_summary.xml | 29 ++++++----- .../main/res/xml/appearance_preferences.xml | 13 +++-- mobile/version.properties | 4 +- wear/build.gradle | 2 +- wear/version.properties | 4 +- 23 files changed, 145 insertions(+), 204 deletions(-) diff --git a/build.gradle b/build.gradle index af2e5d0f3..45a0ba249 100644 --- a/build.gradle +++ b/build.gradle @@ -46,8 +46,8 @@ ext { buildToolsVersion = '23.0.3' // App dependencies - supportLibraryVersion = '27.0.1' - playServicesVersion = '11.6.0' + supportLibraryVersion = '27.0.2' + playServicesVersion = '11.8.0' sdk = 25 buildTools = "25.0.0" //keep 25.0.0 for Continuous Integration diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/database/ListPreferences.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/database/ListPreferences.java index b556069fb..d4b1ecf38 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/database/ListPreferences.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/database/ListPreferences.java @@ -251,39 +251,7 @@ public String getEndDate() { return this.sharedPrefs.getString(PREFS_CURRENT_END_DATE, "2016-05-04"); } - public class GsonDateDeSerializer implements JsonDeserializer { - - private SimpleDateFormat format1 = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a", Locale.US); - private SimpleDateFormat format2 = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss", Locale.US); - - @Override - public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - try { - String j = json.getAsJsonPrimitive().getAsString(); - Date date = parseDate(j); - return date; - } catch (ParseException e) { - Crashlytics.setString("Timezone", String.valueOf(TimeZone.getDefault())); - Crashlytics.setString("Language", Locale.getDefault().getDisplayLanguage()); - Crashlytics.setBool("is24", DateFormat.is24HourFormat(appContext)); - Crashlytics.logException(new JsonParseException(e.getMessage(), e)); - return null; - } - } - - private Date parseDate(String dateString) throws ParseException { - if (dateString != null && dateString.trim().length() > 0) { - try { - return format1.parse(dateString); - } catch (ParseException pe) { - return format2.parse(dateString); - } - } else { - return null; - } - } - } public void isFresh(boolean bool) { Timber.v("Changing isFresh: %s", bool); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java index 0a7d7e880..720e5b1fc 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java @@ -52,6 +52,7 @@ import me.calebjones.spacelaunchnow.ui.main.MainActivity; import me.calebjones.spacelaunchnow.ui.supporter.SupporterHelper; import me.calebjones.spacelaunchnow.utils.GlideApp; +import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.customtab.CustomTabActivityHelper; import me.calebjones.spacelaunchnow.utils.views.CustomOnOffsetChangedListener; @@ -476,7 +477,7 @@ public void onViewClicked() { try { if (launch.getNet() != null) { Date date = launch.getNet(); - SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + SimpleDateFormat df = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - hh:mm a zzz"); df.toLocalizedPattern(); launchDate = df.format(date); } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java index 033f376fa..ba6c8d56a 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java @@ -73,11 +73,7 @@ public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { this.sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext); sharedPreference = ListPreferences.getInstance(mContext); - if (sharedPreference.isNightModeActive(mContext)) { - night = true; - } else { - night = false; - } + night = sharedPreference.isNightModeActive(mContext); View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.launch_list_item, viewGroup, false); return new ViewHolder(v); @@ -107,12 +103,12 @@ public void onBindViewHolder(final ViewHolder holder, int i) { if (launchItem.getStatus() != null && launchItem.getStatus() == 2) { //Get launch date if (sharedPref.getBoolean("local_time", true)) { - SimpleDateFormat df = new SimpleDateFormat("MMMM dd, yyyy."); + SimpleDateFormat df = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy."); df.toLocalizedPattern(); Date date = launchItem.getNet(); launchDate = df.format(date); } else { - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy zzz"); + SimpleDateFormat sdf = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy zzz"); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = launchItem.getNet(); launchDate = sdf.format(date); @@ -123,9 +119,9 @@ public void onBindViewHolder(final ViewHolder holder, int i) { if (sharedPref.getBoolean("local_time", true)) { SimpleDateFormat df; if (sharedPref.getBoolean("24_hour_mode", false)) { - df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - HH:mm zzz"); + df = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - HH:mm zzz"); } else { - df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + df = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - hh:mm a zzz"); } df.toLocalizedPattern(); Date date = launchItem.getNet(); @@ -133,9 +129,9 @@ public void onBindViewHolder(final ViewHolder holder, int i) { } else { SimpleDateFormat sdf; if (sharedPref.getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - HH:mm zzz"); + sdf = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - HH:mm zzz"); } else { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + sdf = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - hh:mm a zzz"); } sdf.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = launchItem.getNet(); @@ -173,22 +169,9 @@ public void onBindViewHolder(final ViewHolder holder, int i) { } } - public String parseDateToMMyyyy(String time) { - String inputPattern = "EEEE, MMM dd yyyy hh:mm a zzz"; - String outputPattern = "MMM yyyy"; - SimpleDateFormat inputFormat = new SimpleDateFormat(inputPattern); - SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern); - - Date date = null; - String str = null; - - try { - date = inputFormat.parse(time); - str = outputFormat.format(date); - } catch (ParseException e) { - e.printStackTrace(); - } - return str; + public String parseDateToMMyyyy(Date date) { + SimpleDateFormat outputFormat = new SimpleDateFormat("MMM yyyy"); + return new SimpleDateFormat("MMM yyyy").format(date); } @Override @@ -199,12 +182,9 @@ public int getItemCount() { @NonNull @Override public String getSectionName(int position) { - SimpleDateFormat df = new SimpleDateFormat("EEEE, MMM dd yyyy hh:mm a zzz"); - df.toLocalizedPattern(); - Date date = launchList.get(position).getNet(); - return parseDateToMMyyyy(df.format(date)); + return parseDateToMMyyyy(date); } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { @@ -215,11 +195,11 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL public ViewHolder(View view) { super(view); - categoryIcon = (ImageView) view.findViewById(R.id.categoryIcon); - title = (TextView) view.findViewById(R.id.launch_rocket); - location = (TextView) view.findViewById(R.id.location); - launch_date = (TextView) view.findViewById(R.id.launch_date); - mission = (TextView) view.findViewById(R.id.mission); + categoryIcon = view.findViewById(R.id.categoryIcon); + title = view.findViewById(R.id.launch_rocket); + location = view.findViewById(R.id.location); + launch_date = view.findViewById(R.id.launch_date); + mission = view.findViewById(R.id.mission); title.setOnClickListener(this); location.setOnClickListener(this); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java index d492c7667..3def8aec0 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java @@ -56,6 +56,7 @@ import me.calebjones.spacelaunchnow.data.models.Constants; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.main.MainActivity; +import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.views.SnackbarHandler; import timber.log.Timber; @@ -356,7 +357,7 @@ public void recreate() { private String formatDatesForTitle(String start_date) { SimpleDateFormat in = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat out = new SimpleDateFormat("LLL yyyy"); + SimpleDateFormat out = Utils.getSimpleDateFormatForUI("LLL yyyy"); Date sDate; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java index 625724975..49b598dd2 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java @@ -114,7 +114,7 @@ public void onBindViewHolder(final ViewHolder holder, int i) { //If we can find the date of the launch add it to the card. if (mission.getLaunch().getNet() != null) { - SimpleDateFormat outformat = new SimpleDateFormat("MMMM dd, yyyy"); + SimpleDateFormat outformat = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); outformat.toLocalizedPattern(); Date date; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java index 1fbfdea43..44965ab65 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java @@ -11,6 +11,7 @@ import android.support.v4.app.ShareCompat; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; +import android.text.format.DateFormat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -30,6 +31,7 @@ import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.Locale; import java.util.TimeZone; import io.realm.RealmList; @@ -181,10 +183,10 @@ public boolean onPreDraw() { } if (launchItem.getProbability() != null && launchItem.getProbability() > 0) { - holder.contentForecast.setText(String.format("%s%%", launchItem.getProbability())); - holder.forecast_container.setVisibility(View.VISIBLE); + holder.contentForecast.setText(String.format("Weather Favorable: %s%%", launchItem.getProbability())); + holder.contentForecast.setVisibility(View.VISIBLE); } else { - holder.forecast_container.setVisibility(View.GONE); + holder.contentForecast.setVisibility(View.GONE); } switch (launchItem.getStatus()) { @@ -365,7 +367,8 @@ public void onTick(long millisUntilFinished) { if (launchItem.getNet() != null) { //Get launch date - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); + + SimpleDateFormat sdf = Utils.getSimpleDateFormatForUI("MMMM d, yyyy"); sdf.toLocalizedPattern(); Date date = launchItem.getNet(); String launchTime = sdf.format(date); @@ -401,7 +404,7 @@ public void onTick(long millisUntilFinished) { } else { launchTime = "To be determined... "; } - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); + SimpleDateFormat sdf = Utils.getSimpleDateFormatForUI("MMMM d, yyyy"); sdf.toLocalizedPattern(); Date date = launchItem.getNet(); holder.launch_date_compact.setText(sdf.format(date)); @@ -498,7 +501,6 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL public ImageView categoryIcon; public CountDownTimer timer; public View countdownView; - public View forecast_container; public TextView contentForecast; public ImageView map_view; @@ -528,7 +530,6 @@ public ViewHolder(View view) { countdownSeconds = view.findViewById(R.id.countdown_seconds); countdownView = view.findViewById(R.id.countdown_layout); - forecast_container = view.findViewById(R.id.forecast_container); contentForecast = view.findViewById(R.id.content_forecast); map_view = view.findViewById(R.id.map_view); @@ -549,7 +550,7 @@ public void onClick(View v) { final Launch launch = launchList.get(position); Intent sendIntent = new Intent(); - SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + SimpleDateFormat df = Utils.getSimpleDateFormatForUI("EEEE, MMMM d, yyyy - hh:mm a zzz"); df.toLocalizedPattern(); Date date = launch.getNet(); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java index 55f6e968c..713dbfe85 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java @@ -88,7 +88,7 @@ public void onClick(View view) { @Override public void onInput(MaterialDialog dialog, CharSequence input) { // Do something - if(DebugAuthManager.getAuthResult(input)){ + if(!input.equals("") && DebugAuthManager.getAuthResult(input)){ goToDebug(); } else { Toast.makeText(context, "Error - Support code was not correct.", Toast.LENGTH_LONG).show(); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java index 4cdd760d6..e8bba129c 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java @@ -40,6 +40,7 @@ public class AppearanceFragment extends BaseSettingFragment implements SharedPre private ColorPreference widgetAccentColor; private ColorPreference widgetTitleColor; private SwitchPreference widgetRoundCorners; + private SwitchPreference widgetHideSettings; private boolean isCustomColor = false; private int[] textPrimaryArray; private int[] textSecondaryArray; @@ -127,7 +128,7 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin Analytics.from(this).sendPreferenceEvent(key); } - if (key.equals("widget_background_color") || key.equals("widget_text_color") || key.equals("widget_secondary_text_color") || key.equals("widget_icon_color") || key.equals("widget_title_text_color") || key.equals("widget_list_accent_color")) { + if (key.equals("widget_background_color") || key.equals("widget_text_color") || key.equals("widget_secondary_text_color") || key.equals("widget_icon_color") || key.equals("widget_title_text_color") || key.equals("widget_list_accent_color") || key.equals("widget_refresh_enabled")) { Intent nextIntent = new Intent(context, WidgetBroadcastReceiver.class); nextIntent.putExtra("updateUIOnly", true); context.sendBroadcast(nextIntent); @@ -178,6 +179,7 @@ private void setupPreferences() { widgetRoundCorners = (SwitchPreference) findPreference("widget_theme_round_corner"); widgetAccentColor = (ColorPreference) findPreference("widget_list_accent_color"); widgetTitleColor = (ColorPreference) findPreference("widget_title_text_color"); + widgetHideSettings = (SwitchPreference) findPreference("widget_refresh_enabled"); if (!SupporterHelper.isSupporter()) { Preference weather = findPreference("weather"); weather.setEnabled(false); @@ -216,6 +218,9 @@ private void setupPreferences() { widgetTitleColor.setEnabled(false); widgetTitleColor.setSelectable(false); + + widgetHideSettings.setEnabled(false); + widgetHideSettings.setSelectable(false); } Preference localTime = findPreference("local_time"); localTime.setOnPreferenceChangeListener(createLocalTimeListener()); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java index 43ce49b0f..ec9117eda 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java @@ -33,6 +33,7 @@ import android.os.Build; import android.support.customtabs.CustomTabsIntent; import android.support.v4.content.ContextCompat; +import android.text.format.DateFormat; import android.view.View; import android.view.ViewPropertyAnimator; import android.view.animation.PathInterpolator; @@ -604,5 +605,10 @@ public static Bitmap getBitMapFromUrl(Context context, String imageURL) { return null; } } + + public static SimpleDateFormat getSimpleDateFormatForUI(String pattern) { + String format = DateFormat.getBestDateTimePattern(Locale.getDefault(), pattern); + return new SimpleDateFormat(format, Locale.getDefault()); + } } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java index 8294fb3c1..187507f9f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java @@ -6,8 +6,10 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; +import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.view.View; import android.widget.RemoteViews; import java.text.SimpleDateFormat; @@ -119,6 +121,8 @@ private void setRefreshIntent(Launch launch) { Intent exploreIntent = new Intent(context, LaunchDetailActivity.class); exploreIntent.putExtra("TYPE", "launch"); exploreIntent.putExtra("launchID", launch.getId()); + exploreIntent.setData(Uri.parse(exploreIntent.toUri(Intent.URI_INTENT_SCHEME))); + exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent actionPendingIntent = PendingIntent.getActivity(context, UniqueIdentifier.getID(), exploreIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.widget_compact_card_frame, actionPendingIntent); @@ -152,6 +156,11 @@ private void setWidgetStyle() { remoteViews.setTextColor(R.id.widget_launch_date, widgetSecondaryTextColor); remoteViews.setInt(R.id.widget_categoryIcon, "setColorFilter", widgetIconColor); remoteViews.setInt(R.id.widget_compact_card_refresh_button, "setColorFilter", widgetIconColor); + if (sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_compact_card_refresh_button, View.GONE); + } else if (!sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_compact_card_refresh_button, View.VISIBLE); + } } private void setLocationName(Launch launchRealm) { @@ -195,9 +204,9 @@ private void setLaunchName(Launch launchRealm) { private void setLaunchDate(Launch launch) { SimpleDateFormat sdf; if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("MMMM dd, yyyy"); + sdf = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); } else { - sdf = new SimpleDateFormat("MMMM dd, yyyy"); + sdf = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); } sdf.toLocalizedPattern(); if (launch.getNet() != null) { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java index 956ff45cc..5c356c5f5 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java @@ -6,6 +6,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; +import android.net.Uri; import android.preference.PreferenceManager; import android.widget.RemoteViews; import android.widget.RemoteViewsService; @@ -118,7 +119,7 @@ public RemoteViews getViewAt(int position) { RemoteViews row = new RemoteViews(context.getPackageName(), R.layout.launch_list_item); String[] title; String launchDate; - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); + SimpleDateFormat sdf = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); //Retrieve missionType if (launch.getMissions().size() != 0) { @@ -186,8 +187,8 @@ public RemoteViews getViewAt(int position) { Intent exploreIntent = new Intent(context, LaunchDetailActivity.class); exploreIntent.putExtra("TYPE", "launch"); exploreIntent.putExtra("launchID", launch.getId()); - exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - + exploreIntent.setData(Uri.parse(exploreIntent.toUri(Intent.URI_INTENT_SCHEME))); + exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); row.setOnClickFillInIntent(R.id.rootview, exploreIntent); return (row); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java index 7e7c68f2f..fbf3baf62 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java @@ -8,6 +8,7 @@ import android.graphics.Color; import android.net.Uri; import android.preference.PreferenceManager; +import android.view.View; import android.widget.RemoteViews; import me.calebjones.spacelaunchnow.R; @@ -157,6 +158,12 @@ private void buildWidget(int appWidgetId) { PendingIntent refreshPending = PendingIntent.getBroadcast(context, 0, nextIntent, 0); remoteViews.setOnClickPendingIntent(R.id.widget_refresh_button, refreshPending); + if (sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_refresh_button, View.GONE); + } else if (!sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_refresh_button, View.VISIBLE); + } + Intent openAppIntent = new Intent(context, MainActivity.class); openAppIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent actionPendingIntent = PendingIntent.getActivity(context, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java index 2f19403c0..87e2605ad 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java @@ -6,8 +6,10 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; +import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.view.View; import android.widget.RemoteViews; import java.text.SimpleDateFormat; @@ -120,7 +122,8 @@ private void setRefreshIntent(Launch launch) { Intent exploreIntent = new Intent(context, LaunchDetailActivity.class); exploreIntent.putExtra("TYPE", "launch"); exploreIntent.putExtra("launchID", launch.getId()); - exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + exploreIntent.setData(Uri.parse(exploreIntent.toUri(Intent.URI_INTENT_SCHEME))); + exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent actionPendingIntent = PendingIntent.getActivity(context, UniqueIdentifier.getID(), exploreIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.widget_countdown_timer_frame, actionPendingIntent); @@ -181,6 +184,11 @@ private void setWidgetStyle() { remoteViews.setTextColor(R.id.countdown_hours_label, widgetSecondaryTextColor); remoteViews.setInt(R.id.widget_refresh_button, "setColorFilter", widgetIconColor); + if (sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_refresh_button, View.GONE); + } else if (!sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_refresh_button, View.VISIBLE); + } } private void setLaunchName(Launch launchRealm) { @@ -193,21 +201,6 @@ private void setLaunchName(Launch launchRealm) { } } - private void setLaunchDate(Launch launch) { - SimpleDateFormat sdf; - if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("MMMM dd, yyyy"); - } else { - sdf = new SimpleDateFormat("MMMM dd, yyyy"); - } - sdf.toLocalizedPattern(); - if (launch.getNet() != null) { - remoteViews.setTextViewText(R.id.widget_launch_date, sdf.format(launch.getNet())); - } else { - remoteViews.setTextViewText(R.id.widget_launch_date, "Unknown Launch Date"); - } - } - private String getLaunchName(Launch launchRealm) { //Replace with launch if (launchRealm.getRocket() != null && launchRealm.getRocket().getName() != null) { diff --git a/mobile/src/main/res/layout-w500dp/content_card_item.xml b/mobile/src/main/res/layout-w500dp/content_card_item.xml index a9ee3fa33..a57e823a1 100644 --- a/mobile/src/main/res/layout-w500dp/content_card_item.xml +++ b/mobile/src/main/res/layout-w500dp/content_card_item.xml @@ -170,6 +170,16 @@ android:textAppearance="@style/MaterialTypography.Regular.Subheading" android:textColor="?android:textColorSecondary" /> + + - - - - - - - + android:text="Launch Window" + android:textAlignment="center" + android:textAppearance="@style/MaterialTypography.Regular.Subheading" /> diff --git a/mobile/src/main/res/layout/app_bar_main.xml b/mobile/src/main/res/layout/app_bar_main.xml index d6000a2b6..64eaf1919 100644 --- a/mobile/src/main/res/layout/app_bar_main.xml +++ b/mobile/src/main/res/layout/app_bar_main.xml @@ -11,7 +11,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay" - app:elevation="8dp"> + app:elevation="12dp"> + app:elevation="12dp"/> diff --git a/mobile/src/main/res/layout/content_card_item.xml b/mobile/src/main/res/layout/content_card_item.xml index c7b1c0d58..6ed45777a 100644 --- a/mobile/src/main/res/layout/content_card_item.xml +++ b/mobile/src/main/res/layout/content_card_item.xml @@ -61,8 +61,8 @@ android:gravity="left" android:maxLines="2" android:text="Unknown Launch" - android:textColor="@color/dark_primary_text_color_selector" android:textAppearance="@style/MaterialTypography.Locale.Title" + android:textColor="@color/dark_primary_text_color_selector" android:textSize="20sp" android:textStyle="bold" /> @@ -106,13 +106,13 @@ android:id="@+id/content_status" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/titleBarColor" android:ellipsize="end" android:gravity="center" android:paddingBottom="8dp" android:paddingTop="4dp" android:singleLine="false" android:text="Unknown Launch Status" - android:background="?attr/titleBarColor" android:textAlignment="center" android:textColor="@color/dark_primary_text_color_selector" android:textSize="20sp" @@ -125,7 +125,6 @@ android:orientation="vertical"> - + + - - - - - - - - + android:text="Launch Window" + android:textAlignment="center" + android:textAppearance="@style/MaterialTypography.Regular.Subheading" /> - + Date: Tue, 2 Jan 2018 02:08:30 -0500 Subject: [PATCH 26/41] This too --- .../fragments/SummaryDetailFragment.java | 110 ++++++++---------- 1 file changed, 47 insertions(+), 63 deletions(-) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java index 34710bd6b..370029d1f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java @@ -37,10 +37,12 @@ import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; +import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.Locale; import java.util.TimeZone; import butterknife.BindView; @@ -54,7 +56,6 @@ import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.events.LaunchEvent; -import me.calebjones.spacelaunchnow.content.services.LibraryDataManager; import me.calebjones.spacelaunchnow.content.util.DialogAdapter; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Pad; @@ -107,10 +108,6 @@ public class SummaryDetailFragment extends BaseFragment { TextView launch_date_title; @BindView(R.id.date) TextView date; - @BindView(R.id.launch_window_start) - TextView launch_window_start; - @BindView(R.id.launch_window_end) - TextView launch_window_end; @BindView(R.id.launch_status) TextView launch_status; @BindView(R.id.watchButton) @@ -183,6 +180,10 @@ public class SummaryDetailFragment extends BaseFragment { WeatherIconView weatherPrecipIcon; @BindView(R.id.weather_wind_speed_icon) WeatherIconView weatherSpeedIcon; + @BindView(R.id.launch_window_title) + TextView launchWindowTitle; + @BindView(R.id.launch_window_text) + TextView launchWindowText; @Override public void onCreate(Bundle savedInstanceState) { @@ -573,7 +574,7 @@ public boolean onPreDraw() { //Setup SimpleDateFormat to parse out getNet date. SimpleDateFormat input = new SimpleDateFormat("MMMM dd, yyyy hh:mm:ss zzz"); - SimpleDateFormat output = new SimpleDateFormat("MMMM dd, yyyy"); + SimpleDateFormat output = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); input.toLocalizedPattern(); Date mDate; @@ -674,11 +675,11 @@ public void onListItemSelected(int index, MaterialSimpleListItem item, boolean l date.setText(dateText); - if (detailLaunch.getWsstamp() > 0 && detailLaunch.getWestamp() > 0) { + if (detailLaunch.getWindowstart() != null && detailLaunch.getWindowstart() != null) { setWindowStamp(); } else { - launch_window_start.setVisibility(View.GONE); - launch_window_end.setVisibility(View.GONE); + launchWindowTitle.setVisibility(View.GONE); + launchWindowText.setVisibility(View.GONE); } } catch (NullPointerException e) { Timber.e(e); @@ -883,64 +884,47 @@ private void getLaunchVehicle(Launch vehicle) { private void setWindowStamp() { // Create a DateFormatter object for displaying date in specified format. - SimpleDateFormat formatter; - if (sharedPref.getBoolean("24_hour_mode", false)) { - formatter = new SimpleDateFormat("HH:mm zzz"); - } else { - formatter = new SimpleDateFormat("hh:mm a zzz"); - } - // Create a calendar object that will convert the date and time value in milliseconds to date. - Calendar calendarStart = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - long startDate = detailLaunch.getWsstamp(); - startDate = startDate * 1000; - calendarStart.setTimeInMillis(startDate); - String start = formatter.format(calendarStart.getTime()); - - // Create a calendar object that will convert the date and time value in milliseconds to date. - Calendar calendarEnd = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - long endDate = detailLaunch.getWestamp(); - endDate = endDate * 1000; - calendarEnd.setTimeInMillis(endDate); - String end = formatter.format(calendarEnd.getTime()); - - if (!start.equals(end)) { - if (start.length() == 0 - || end.length() == 0) { - launch_window_start.setText(String.format("Launch Time: %s", - start)); - launch_window_end.setVisibility(View.GONE); - } else { - launch_window_start.setText(String.format("Window Start: %s", - start)); - launch_window_end.setVisibility(View.VISIBLE); - launch_window_end.setText(String.format("Window End: %s", - end)); + Date windowStart = detailLaunch.getWindowstart(); + Date windowEnd = detailLaunch.getWindowend(); + + boolean twentyFourHourMode = sharedPref.getBoolean("24_hour_mode", false); + DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()); + + if (windowStart.equals(windowEnd)){ + // Window Start and Window End match - meaning instantaneous. + if (twentyFourHourMode){ + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } - } else { - launch_window_start.setText(String.format("Launch Time: %s", - start)); - launch_window_end.setVisibility(View.GONE); - } - } - private void setWindowStartEnd() { - if (!detailLaunch.getWindowstart().equals(detailLaunch.getWindowend())) { - if (detailLaunch.getWindowstart().toString().length() > 0 - || detailLaunch.getWindowend().toString().length() > 0) { - launch_window_start.setText("Launch Window unavailable."); - launch_window_end.setVisibility(View.INVISIBLE); - } else { - launch_window_start.setText(String.format("Window Start: %s", - detailLaunch.getWindowstart())); - launch_window_end.setVisibility(View.VISIBLE); - launch_window_end.setText(String.format("Window End: %s", - detailLaunch.getWindowend())); + TimeZone timeZone = dateFormat.getTimeZone(); + launchWindowTitle.setText("Launch Window"); + launchWindowText.setText(String.format("%s %s", + dateFormat.format(windowStart), + timeZone.getDisplayName(false, TimeZone.SHORT))); + } else if (windowStart.after(windowEnd)) { + // Launch data is not trustworthy - start is after end. + if (twentyFourHourMode){ + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } - } else { - launch_window_start.setText(String.format("Launch Time: %s", - detailLaunch.getWindowstart())); - launch_window_end.setVisibility(View.INVISIBLE); + + TimeZone timeZone = dateFormat.getTimeZone(); + launchWindowTitle.setText("Launch Window"); + launchWindowText.setText(String.format("%s %s", + dateFormat.format(windowStart), + timeZone.getDisplayName(false, TimeZone.SHORT))); + } else if (windowStart.before(windowEnd)){ + // Launch Window is properly configured + if (twentyFourHourMode){ + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + TimeZone timeZone = dateFormat.getTimeZone(); + launchWindowTitle.setText("Launch Window"); + launchWindowText.setText(String.format("%s - %s %s", + dateFormat.format(windowStart), + dateFormat.format(windowEnd), + timeZone.getDisplayName(false, TimeZone.SHORT))); } } From 378ffe2d93a23639757925f8c8ec0e5228cc809f Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Tue, 2 Jan 2018 15:38:18 -0500 Subject: [PATCH 27/41] 2.0.0 Beta II --- build.gradle | 2 +- mobile/build.gradle | 9 ++++++--- mobile/src/main/res/layout/activity_launch_detail.xml | 3 ++- mobile/src/main/res/layout/app_bar_main.xml | 10 ++++++---- mobile/version.properties | 4 ++-- wear/version.properties | 4 ++-- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 45a0ba249..174d89f6e 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ buildscript { // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files classpath 'org.moallemi.gradle.advanced-build-version:gradle-plugin:1.6.0' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' } diff --git a/mobile/build.gradle b/mobile/build.gradle index 3c1f96080..4bc056bda 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -7,7 +7,7 @@ buildscript { } dependencies { - classpath 'io.fabric.tools:gradle:1.24.0' + classpath 'io.fabric.tools:gradle:1.+' classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.2' } } @@ -31,7 +31,7 @@ advancedVersioning { } codeOptions { versionCodeType VersionCodeType.AUTO_INCREMENT_ONE_STEP - dependsOnTasks 'release', 'beta' + dependsOnTasks 'release', 'beta', 'alpha' } outputOptions { @@ -109,6 +109,7 @@ android { renderscriptOptimLevel 3 versionNameSuffix "-debug-b${appVersionCode}" minifyEnabled true + useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro' } @@ -116,6 +117,7 @@ android { zipAlignEnabled true minifyEnabled true shrinkResources true + useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.releaseConfig } @@ -127,6 +129,7 @@ android { applicationIdSuffix ".test" versionNameSuffix "-test" minifyEnabled true + useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro' testProguardFile('proguard-rules-test.pro') matchingFallbacks = ['debug', 'release'] @@ -203,7 +206,7 @@ dependencies { // Architecture and Tools implementation 'com.jonathanfinerty.once:once:1.2.2' implementation 'org.greenrobot:eventbus:3.1.1' - implementation('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') { + implementation('com.crashlytics.sdk.android:crashlytics:2.8.0@aar') { transitive = true } implementation 'com.jakewharton.timber:timber:4.6.0' diff --git a/mobile/src/main/res/layout/activity_launch_detail.xml b/mobile/src/main/res/layout/activity_launch_detail.xml index c2326d67c..8a860d944 100644 --- a/mobile/src/main/res/layout/activity_launch_detail.xml +++ b/mobile/src/main/res/layout/activity_launch_detail.xml @@ -10,6 +10,7 @@ android:id="@+id/detail.appbar" android:layout_width="match_parent" android:layout_height="wrap_content" + android:elevation="8dp" android:fitsSystemWindows="true"> + android:elevation="8dp"> + android:elevation="8dp" + app:popupTheme="@style/AppTheme.PopupOverlay"/> + android:layout_height="match_parent" + > Date: Tue, 2 Jan 2018 17:19:02 -0500 Subject: [PATCH 28/41] Work on YouTube video embed. --- mobile/build.gradle | 1 + mobile/libs/YouTubeAndroidPlayerApi.jar | Bin 0 -> 106430 bytes .../fragments/SummaryDetailFragment.java | 50 +++++++++++++----- .../res/layout-w500dp/content_card_item.xml | 50 +++++++----------- .../layout-w500dp/detail_launch_summary.xml | 18 +++++++ mobile/src/main/res/layout/app_bar_main.xml | 6 ++- .../src/main/res/layout/content_card_item.xml | 42 ++++++--------- .../main/res/layout/detail_launch_summary.xml | 29 ++++++++-- mobile/src/main/res/values/strings.xml | 3 ++ 9 files changed, 121 insertions(+), 78 deletions(-) create mode 100644 mobile/libs/YouTubeAndroidPlayerApi.jar diff --git a/mobile/build.gradle b/mobile/build.gradle index 4bc056bda..37b578808 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -263,4 +263,5 @@ dependencies { implementation 'com.mikepenz:community-material-typeface:2.0.46.1@aar' implementation 'com.github.pwittchen:weathericonview:1.1.0' implementation 'com.mikepenz:fontawesome-typeface:4.7.0.0@aar' + implementation files('libs/YouTubeAndroidPlayerApi.jar') } diff --git a/mobile/libs/YouTubeAndroidPlayerApi.jar b/mobile/libs/YouTubeAndroidPlayerApi.jar new file mode 100644 index 0000000000000000000000000000000000000000..0acbebde9d65136b7a4f43461eacf190725a0333 GIT binary patch literal 106430 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 literal 0 HcmV?d00001 diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java index 370029d1f..ebaa0d4c0 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java @@ -10,6 +10,7 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentTransaction; import android.support.v4.content.ContextCompat; import android.support.v4.widget.NestedScrollView; import android.support.v7.widget.AppCompatButton; @@ -31,6 +32,10 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.simplelist.MaterialSimpleListItem; import com.github.pwittchen.weathericonview.WeatherIconView; +import com.google.android.youtube.player.YouTubeInitializationResult; +import com.google.android.youtube.player.YouTubePlayer; +import com.google.android.youtube.player.YouTubePlayerFragment; +import com.google.android.youtube.player.YouTubePlayerSupportFragment; import com.mypopsy.maps.StaticMap; import org.greenrobot.eventbus.EventBus; @@ -59,8 +64,8 @@ import me.calebjones.spacelaunchnow.content.util.DialogAdapter; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Pad; -import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.data.models.realm.RealmStr; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; @@ -71,15 +76,17 @@ import timber.log.Timber; -public class SummaryDetailFragment extends BaseFragment { +public class SummaryDetailFragment extends BaseFragment implements YouTubePlayer.OnInitializedListener { + @BindView(R.id.youtube_card) + CardView youtubeCard; private SharedPreferences sharedPref; private static ListPreferences sharedPreference; private Context context; private CountDownTimer timer; public Launch detailLaunch; private RocketDetail launchVehicle; - + private YouTubePlayerSupportFragment youTubePlayerFragment; private boolean nightMode; @BindView(R.id.content_TMinus_status) @@ -207,6 +214,11 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa View view = inflater.inflate(R.layout.detail_launch_summary, container, false); ButterKnife.bind(this, view); + YouTubePlayerSupportFragment youTubePlayerFragment = YouTubePlayerSupportFragment.newInstance(); + FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); + transaction.add(R.id.youtube_view, youTubePlayerFragment).commit(); + youTubePlayerFragment.initialize(context.getResources().getString(R.string.GoogleMapsKey), this); + return view; } @@ -891,9 +903,9 @@ private void setWindowStamp() { boolean twentyFourHourMode = sharedPref.getBoolean("24_hour_mode", false); DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()); - if (windowStart.equals(windowEnd)){ + if (windowStart.equals(windowEnd)) { // Window Start and Window End match - meaning instantaneous. - if (twentyFourHourMode){ + if (twentyFourHourMode) { dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } @@ -904,7 +916,7 @@ private void setWindowStamp() { timeZone.getDisplayName(false, TimeZone.SHORT))); } else if (windowStart.after(windowEnd)) { // Launch data is not trustworthy - start is after end. - if (twentyFourHourMode){ + if (twentyFourHourMode) { dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } @@ -913,9 +925,9 @@ private void setWindowStamp() { launchWindowText.setText(String.format("%s %s", dateFormat.format(windowStart), timeZone.getDisplayName(false, TimeZone.SHORT))); - } else if (windowStart.before(windowEnd)){ + } else if (windowStart.before(windowEnd)) { // Launch Window is properly configured - if (twentyFourHourMode){ + if (twentyFourHourMode) { dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } @@ -954,11 +966,6 @@ public void onStop() { super.onStop(); } - @Override - public void onDestroyView() { - super.onDestroyView(); - } - @OnClick(R.id.map_view_summary) public void onViewClicked() { String location = detailLaunch.getLocation().getName(); @@ -980,4 +987,21 @@ public void onViewClicked() { context.startActivity(mapIntent); } } + + @Override + public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean restored) { + if (!restored) { + youTubePlayer.cueVideo("fhWaJi1Hsfo"); // Plays https://www.youtube.com/watch?v=fhWaJi1Hsfo + } + } + + @Override + public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) { + if (youTubeInitializationResult.isUserRecoverableError()) { + youTubeInitializationResult.getErrorDialog(getActivity(), 1).show(); + } else { + String error = String.format(getString(R.string.player_error), youTubeInitializationResult.toString()); + Toast.makeText(getContext(), error, Toast.LENGTH_LONG).show(); + } + } } diff --git a/mobile/src/main/res/layout-w500dp/content_card_item.xml b/mobile/src/main/res/layout-w500dp/content_card_item.xml index a57e823a1..8bdaadd33 100644 --- a/mobile/src/main/res/layout-w500dp/content_card_item.xml +++ b/mobile/src/main/res/layout-w500dp/content_card_item.xml @@ -184,28 +184,25 @@ android:id="@+id/content_mission_description_view" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" - android:paddingBottom="8dp"> + android:orientation="vertical"> - @@ -214,9 +211,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="8dp" - android:paddingLeft="28dp" - android:paddingRight="28dp" android:paddingTop="8dp" + android:layout_marginStart="@dimen/material_baseline_grid_2.5x" + android:layout_marginEnd="@dimen/material_baseline_grid_2.5x" android:textColor="?android:textColorSecondary" android:textSize="14sp" /> @@ -224,37 +221,28 @@ + android:text="Watch Live" /> + android:layout_alignParentEnd="true" + android:layout_marginEnd="@dimen/material_baseline_grid_2x" + android:text="Share" /> + android:text="Explore" /> diff --git a/mobile/src/main/res/layout-w500dp/detail_launch_summary.xml b/mobile/src/main/res/layout-w500dp/detail_launch_summary.xml index 5e4f7723d..f99f4e02e 100644 --- a/mobile/src/main/res/layout-w500dp/detail_launch_summary.xml +++ b/mobile/src/main/res/layout-w500dp/detail_launch_summary.xml @@ -16,6 +16,24 @@ android:layout_height="fill_parent" android:orientation="vertical"> + + + + + + + android:layout_height="match_parent"> + android:orientation="vertical"> @@ -213,9 +211,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="8dp" - android:paddingLeft="28dp" - android:paddingRight="28dp" android:paddingTop="8dp" + android:layout_marginStart="@dimen/material_baseline_grid_2.5x" + android:layout_marginEnd="@dimen/material_baseline_grid_2.5x" android:textColor="?android:textColorSecondary" android:textSize="14sp" /> @@ -223,34 +221,27 @@ + android:text="Watch Live" /> diff --git a/mobile/src/main/res/layout/detail_launch_summary.xml b/mobile/src/main/res/layout/detail_launch_summary.xml index c01819a28..04b8d0a34 100644 --- a/mobile/src/main/res/layout/detail_launch_summary.xml +++ b/mobile/src/main/res/layout/detail_launch_summary.xml @@ -1,6 +1,5 @@ - + + + + + + @@ -113,8 +132,8 @@ android:paddingTop="8dp" android:text="Estimated Launch Date" android:textAlignment="center" - android:textSize="18sp" - android:textAppearance="@style/MaterialTypography.Regular.Subheading"/> + android:textAppearance="@style/MaterialTypography.Regular.Subheading" + android:textSize="18sp" /> Get to know the vehicles that have taken us to orbit. http://res.cloudinary.com/dnkkbfy3m/image/upload/v1462465326/navbar_one_sqfhes.png This application, Space Launch Now, started as a simple weekend project. In the course of a year its grown to nearly 10,000 active users. I am incredibly appreciative to everyone that has taken the time to report bugs, give feedback, participate in BETA\'s and become supporters. + Error initializing YouTube player: %s + Jump To + Seconds From 5f01a88f178bc032249004f2c38436ee1c39e740 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Wed, 3 Jan 2018 13:48:21 -0500 Subject: [PATCH 29/41] fine --- mobile/build.gradle | 18 +-- mobile/libs/YouTubeAndroidPlayerApi.jar | Bin 0 -> 106430 bytes mobile/src/main/assets/CHANGELOG.md | 13 +- .../spacelaunchnow/common/BaseActivity.java | 25 ++-- .../content/database/ListPreferences.java | 32 ----- .../activity/LaunchDetailActivity.java | 132 +++++++++++------- .../fragments/AgencyDetailFragment.java | 8 ++ .../fragments/MissionDetailFragment.java | 2 + .../spacelaunchnow/ui/main/MainActivity.java | 6 +- .../ui/main/launches/ListAdapter.java | 52 +++---- .../launches/PreviousLaunchesFragment.java | 3 +- .../ui/main/missions/MissionAdapter.java | 2 +- .../ui/main/next/CardAdapter.java | 17 +-- .../ui/settings/AboutActivity.java | 2 +- .../fragments/AppearanceFragment.java | 7 +- .../spacelaunchnow/utils/Utils.java | 6 + .../launchcard/LaunchCardCompactManager.java | 13 +- .../widget/launchlist/LaunchListFactory.java | 7 +- .../widget/launchlist/LaunchListManager.java | 20 ++- .../wordtimer/LaunchWordTimerManager.java | 25 ++-- .../src/main/res/drawable/rounded_bottom.xml | 6 + .../res/layout-w500dp/content_card_item.xml | 89 ++++-------- .../layout-w500dp/detail_launch_summary.xml | 47 +++++-- .../res/layout/activity_launch_detail.xml | 5 +- mobile/src/main/res/layout/app_bar_main.xml | 9 +- .../src/main/res/layout/content_card_item.xml | 95 ++++--------- .../main/res/layout/detail_launch_summary.xml | 81 ++++++++--- .../widget_launch_card_compact_dark.xml | 5 +- .../widget_launch_card_compact_large_dark.xml | 4 +- .../main/res/layout/widget_launch_list.xml | 25 ++-- mobile/src/main/res/values/colors.xml | 10 +- mobile/src/main/res/values/strings.xml | 3 + .../main/res/xml/appearance_preferences.xml | 13 +- mobile/version.properties | 4 +- wear/build.gradle | 2 +- wear/version.properties | 4 +- 36 files changed, 417 insertions(+), 375 deletions(-) create mode 100644 mobile/libs/YouTubeAndroidPlayerApi.jar create mode 100644 mobile/src/main/res/drawable/rounded_bottom.xml diff --git a/mobile/build.gradle b/mobile/build.gradle index 54fe83652..a8db904be 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -76,14 +76,7 @@ android { buildToolsVersion '26.0.2' defaultConfig { -// splits { -// abi { -// enable true -// reset() -// include 'x86_64', 'x86', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips' -// universalApk false -// } -// } + applicationId "me.calebjones.spacelaunchnow" manifestPlaceholders = [appNameLabel : "@string/application_name", @@ -113,6 +106,14 @@ android { } release { +// splits { +// abi { +// enable true +// reset() +// include 'x86_64', 'x86', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips' +// universalApk false +// } +// } zipAlignEnabled true minifyEnabled true shrinkResources true @@ -179,6 +180,7 @@ dependencies { wearApp project(':wear') implementation project(':glidepalette') implementation project(path: ':data') + implementation files('libs/YouTubeAndroidPlayerApi.jar') // Android Official Libraries implementation 'com.android.support.constraint:constraint-layout:1.0.2' diff --git a/mobile/libs/YouTubeAndroidPlayerApi.jar b/mobile/libs/YouTubeAndroidPlayerApi.jar new file mode 100644 index 0000000000000000000000000000000000000000..0acbebde9d65136b7a4f43461eacf190725a0333 GIT binary patch literal 106430 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 literal 0 HcmV?d00001 diff --git a/mobile/src/main/assets/CHANGELOG.md b/mobile/src/main/assets/CHANGELOG.md index 025b85655..f51d8c8d9 100644 --- a/mobile/src/main/assets/CHANGELOG.md +++ b/mobile/src/main/assets/CHANGELOG.md @@ -3,16 +3,19 @@ A space launch tracker for Android using data from the Launch Library API. [View the latest releases here.](https://github.com/ItsCalebJones/SpaceLaunchNow-Android/releases) ## Changelog -#### Updated 11-25-2017 +#### Updated 12-31-2017 --- ### Version 2.0.0 (Latest) #### Overview -Color. Colors everywhere. Widgets. +Took a lot of time to refine the current UI design, adding color and tightening up keylines wherever I could. Also added a new widget for Supporters - a list of upcoming launches. #### Changelog -* blah -* blah -* blah +* Added a new Launch List widget for Supporters. +* Added links to Discord, Twitter, Facebook, and Website. +* Improved feedback mechanism - now have the option to email from the app. +* Improved general UI with colors and better layouts. +* Refined layouts and function of existing widgets. +* Fixed a bug with not displaying the time in 24-hour mode on Android wear. --- ### Version 1.8.2 (Beta) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/common/BaseActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/common/BaseActivity.java index ea7b73438..404bc254e 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/common/BaseActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/common/BaseActivity.java @@ -9,9 +9,12 @@ import android.support.v7.app.AppCompatActivity; import android.util.TypedValue; +import java.util.TimeZone; + import io.realm.Realm; import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; +import timber.log.Timber; public class BaseActivity extends AppCompatActivity { @@ -27,28 +30,14 @@ public BaseActivity (String screenName){ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Timber.d("onCreate"); realm = Realm.getDefaultInstance(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = getTheme(); - theme.resolveAttribute(R.attr.recentBarColor, typedValue, true); - int color = typedValue.data; - - Bitmap bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round); - ActivityManager.TaskDescription td = new ActivityManager.TaskDescription(null, bm, color); - - setTaskDescription(td); - if (bm != null) { - bm.recycle(); - } - } } @Override protected void onDestroy() { super.onDestroy(); + Timber.d("onDestroy"); Analytics.from(this).sendScreenView(name, "Activity destroyed."); realm.close(); } @@ -56,21 +45,25 @@ protected void onDestroy() { @Override public void onStart() { super.onStart(); + Timber.d("onStart"); Analytics.from(this).sendScreenView(name, name + " started."); } @Override public void onResume() { super.onResume(); + Timber.d("onResume"); Analytics.from(this).sendScreenView(name, name + " resumed."); } @Override public void onPause() { super.onPause(); + Timber.d("onPause"); Analytics.from(this).notifyGoneBackground(); } + public Realm getRealm() { return realm; } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/database/ListPreferences.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/database/ListPreferences.java index b556069fb..d4b1ecf38 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/content/database/ListPreferences.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/content/database/ListPreferences.java @@ -251,39 +251,7 @@ public String getEndDate() { return this.sharedPrefs.getString(PREFS_CURRENT_END_DATE, "2016-05-04"); } - public class GsonDateDeSerializer implements JsonDeserializer { - - private SimpleDateFormat format1 = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a", Locale.US); - private SimpleDateFormat format2 = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss", Locale.US); - - @Override - public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - try { - String j = json.getAsJsonPrimitive().getAsString(); - Date date = parseDate(j); - return date; - } catch (ParseException e) { - Crashlytics.setString("Timezone", String.valueOf(TimeZone.getDefault())); - Crashlytics.setString("Language", Locale.getDefault().getDisplayLanguage()); - Crashlytics.setBool("is24", DateFormat.is24HourFormat(appContext)); - Crashlytics.logException(new JsonParseException(e.getMessage(), e)); - return null; - } - } - - private Date parseDate(String dateString) throws ParseException { - if (dateString != null && dateString.trim().length() > 0) { - try { - return format1.parse(dateString); - } catch (ParseException pe) { - return format2.parse(dateString); - } - } else { - return null; - } - } - } public void isFresh(boolean bool) { Timber.v("Changing isFresh: %s", bool); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java index 0a7d7e880..fc248e409 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/activity/LaunchDetailActivity.java @@ -24,6 +24,7 @@ import com.google.android.gms.ads.AdListener; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdView; +import com.google.android.youtube.player.YouTubePlayer; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -52,6 +53,7 @@ import me.calebjones.spacelaunchnow.ui.main.MainActivity; import me.calebjones.spacelaunchnow.ui.supporter.SupporterHelper; import me.calebjones.spacelaunchnow.utils.GlideApp; +import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.customtab.CustomTabActivityHelper; import me.calebjones.spacelaunchnow.utils.views.CustomOnOffsetChangedListener; @@ -100,7 +102,8 @@ public class LaunchDetailActivity extends BaseActivity private Context context; private TabsAdapter tabAdapter; private int statusColor; - + public YouTubePlayer youTubePlayer; + public boolean isYouTubePlayerFullScreen; public String response; public Launch launch; @@ -167,64 +170,67 @@ public void onAdFailedToLoad(int error) { if (type != null && type.equals("launch")) { final int id = mIntent.getIntExtra("launchID", 0); - detailSwipeRefresh.setRefreshing(true); + Launch launch = getRealm().where(Launch.class).equalTo("id", id).findFirst(); if (launch != null) { updateViews(launch); } - DataClient.getInstance().getLaunchById(id, true, new Callback() { - @Override - public void onResponse(Call call, Response response) { - Realm realm = Realm.getDefaultInstance(); - if (response.isSuccessful()) { - final RealmList items = new RealmList<>(response.body().getLaunches()); - if (items.size() == 1) { - final Launch item = items.first(); - realm.executeTransactionAsync(new Realm.Transaction() { - @Override - public void execute(Realm bgRealm) { - Launch previous = bgRealm.where(Launch.class) - .equalTo("id", item.getId()) - .findFirst(); - if (previous != null) { - item.setEventID(previous.getEventID()); - item.setSyncCalendar(previous.syncCalendar()); - item.setLaunchTimeStamp(previous.getLaunchTimeStamp()); - item.setIsNotifiedDay(previous.getIsNotifiedDay()); - item.setIsNotifiedHour(previous.getIsNotifiedHour()); - item.setIsNotifiedTenMinute(previous.getIsNotifiedTenMinute()); - item.setNotifiable(previous.isNotifiable()); + if (launch != null && savedInstanceState == null) { + detailSwipeRefresh.setRefreshing(true); + DataClient.getInstance().getLaunchById(id, true, new Callback() { + @Override + public void onResponse(Call call, Response response) { + Realm realm = Realm.getDefaultInstance(); + if (response.isSuccessful()) { + final RealmList items = new RealmList<>(response.body().getLaunches()); + if (items.size() == 1) { + final Launch item = items.first(); + realm.executeTransactionAsync(new Realm.Transaction() { + @Override + public void execute(Realm bgRealm) { + Launch previous = bgRealm.where(Launch.class) + .equalTo("id", item.getId()) + .findFirst(); + if (previous != null) { + item.setEventID(previous.getEventID()); + item.setSyncCalendar(previous.syncCalendar()); + item.setLaunchTimeStamp(previous.getLaunchTimeStamp()); + item.setIsNotifiedDay(previous.getIsNotifiedDay()); + item.setIsNotifiedHour(previous.getIsNotifiedHour()); + item.setIsNotifiedTenMinute(previous.getIsNotifiedTenMinute()); + item.setNotifiable(previous.isNotifiable()); + } + item.getLocation().setPrimaryID(); + bgRealm.copyToRealmOrUpdate(item); + Timber.v("Updated detailLaunch: %s", item.getId()); } - item.getLocation().setPrimaryID(); - bgRealm.copyToRealmOrUpdate(item); - Timber.v("Updated detailLaunch: %s", item.getId()); - } - - }, new Realm.Transaction.OnSuccess() { - @Override - public void onSuccess() { - sendUpdateView(id); - } - }); + + }, new Realm.Transaction.OnSuccess() { + @Override + public void onSuccess() { + sendUpdateView(id); + } + }); + } + } else { + sendUpdateView(id); } - } else { - sendUpdateView(id); + realm.close(); + detailSwipeRefresh.setRefreshing(false); } - realm.close(); - detailSwipeRefresh.setRefreshing(false); - } - @Override - public void onFailure(Call call, Throwable t) { - Realm realm = Realm.getDefaultInstance(); - Launch item = realm.where(Launch.class) - .equalTo("id", id) - .findFirst(); - updateViews(item); - realm.close(); - detailSwipeRefresh.setRefreshing(false); - } - }); + @Override + public void onFailure(Call call, Throwable t) { + Realm realm = Realm.getDefaultInstance(); + Launch item = realm.where(Launch.class) + .equalTo("id", id) + .findFirst(); + updateViews(item); + realm.close(); + detailSwipeRefresh.setRefreshing(false); + } + }); + } } @@ -251,6 +257,7 @@ public void onClick(View v) { tabLayout.setupWithViewPager(viewPager); } + private void sendUpdateView(int id){ Launch item = getRealm().where(Launch.class) .equalTo("id", id) @@ -476,7 +483,7 @@ public void onViewClicked() { try { if (launch.getNet() != null) { Date date = launch.getNet(); - SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + SimpleDateFormat df = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - hh:mm a zzz"); df.toLocalizedPattern(); launchDate = df.format(date); } @@ -515,4 +522,25 @@ public void onMessageEvent(LaunchRequestEvent event) { EventBus.getDefault().post(new LaunchEvent(launch)); } + @Override + protected void onSaveInstanceState(final Bundle outState) { + super.onSaveInstanceState(outState); + + } + + @Override + protected void onRestoreInstanceState(final Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + + } + + @Override + public void onBackPressed() { + if (youTubePlayer != null && isYouTubePlayerFullScreen){ + youTubePlayer.setFullscreen(false); + } else { + super.onBackPressed(); + } + } + } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java index ee82ac2f0..afa8a9fe8 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/AgencyDetailFragment.java @@ -94,6 +94,14 @@ public class AgencyDetailFragment extends BaseFragment { @BindView(R.id.vehicle_agency_title) TextView vehicle_agency_title; + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setScreenName("Agency Detail Fragment"); + // retain this fragment + setRetainInstance(true); + } + @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java index c3478ca87..ca85f30a6 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/MissionDetailFragment.java @@ -72,6 +72,8 @@ public class MissionDetailFragment extends BaseFragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setScreenName("Mission Detail Fragment"); + // retain this fragment + setRetainInstance(true); } @Nullable diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java index 258fa9440..63438d7e4 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java @@ -235,14 +235,14 @@ public void onAdLoaded() { .withIcon(CommunityMaterial.Icon.cmd_discord) .withLevel(2) .withName("Discord") - .withDescription("Hop on Discord during launches!") + .withDescription("Join the Community") .withIdentifier(R.id.menu_discord) .withSelectable(false), new SecondaryDrawerItem() .withIcon(CommunityMaterial.Icon.cmd_twitter) .withLevel(2) .withName("Twitter") - .withDescription("Connect on Twitter!") + .withDescription("Connect on Twitter") .withIdentifier(R.id.menu_twitter) .withSelectable(false), new SecondaryDrawerItem() @@ -256,7 +256,7 @@ public void onAdLoaded() { .withIcon(CommunityMaterial.Icon.cmd_web) .withLevel(2) .withName("On the Web") - .withDescription("Bookmark spacelaunchnow.me") + .withDescription("Space Launch Now - Official Site") .withIdentifier(R.id.menu_website) .withSelectable(false) ), diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java index 033f376fa..ba6c8d56a 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/ListAdapter.java @@ -73,11 +73,7 @@ public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { this.sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext); sharedPreference = ListPreferences.getInstance(mContext); - if (sharedPreference.isNightModeActive(mContext)) { - night = true; - } else { - night = false; - } + night = sharedPreference.isNightModeActive(mContext); View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.launch_list_item, viewGroup, false); return new ViewHolder(v); @@ -107,12 +103,12 @@ public void onBindViewHolder(final ViewHolder holder, int i) { if (launchItem.getStatus() != null && launchItem.getStatus() == 2) { //Get launch date if (sharedPref.getBoolean("local_time", true)) { - SimpleDateFormat df = new SimpleDateFormat("MMMM dd, yyyy."); + SimpleDateFormat df = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy."); df.toLocalizedPattern(); Date date = launchItem.getNet(); launchDate = df.format(date); } else { - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy zzz"); + SimpleDateFormat sdf = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy zzz"); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = launchItem.getNet(); launchDate = sdf.format(date); @@ -123,9 +119,9 @@ public void onBindViewHolder(final ViewHolder holder, int i) { if (sharedPref.getBoolean("local_time", true)) { SimpleDateFormat df; if (sharedPref.getBoolean("24_hour_mode", false)) { - df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - HH:mm zzz"); + df = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - HH:mm zzz"); } else { - df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + df = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - hh:mm a zzz"); } df.toLocalizedPattern(); Date date = launchItem.getNet(); @@ -133,9 +129,9 @@ public void onBindViewHolder(final ViewHolder holder, int i) { } else { SimpleDateFormat sdf; if (sharedPref.getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - HH:mm zzz"); + sdf = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - HH:mm zzz"); } else { - sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + sdf = Utils.getSimpleDateFormatForUI("EEEE, MMMM dd, yyyy - hh:mm a zzz"); } sdf.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = launchItem.getNet(); @@ -173,22 +169,9 @@ public void onBindViewHolder(final ViewHolder holder, int i) { } } - public String parseDateToMMyyyy(String time) { - String inputPattern = "EEEE, MMM dd yyyy hh:mm a zzz"; - String outputPattern = "MMM yyyy"; - SimpleDateFormat inputFormat = new SimpleDateFormat(inputPattern); - SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern); - - Date date = null; - String str = null; - - try { - date = inputFormat.parse(time); - str = outputFormat.format(date); - } catch (ParseException e) { - e.printStackTrace(); - } - return str; + public String parseDateToMMyyyy(Date date) { + SimpleDateFormat outputFormat = new SimpleDateFormat("MMM yyyy"); + return new SimpleDateFormat("MMM yyyy").format(date); } @Override @@ -199,12 +182,9 @@ public int getItemCount() { @NonNull @Override public String getSectionName(int position) { - SimpleDateFormat df = new SimpleDateFormat("EEEE, MMM dd yyyy hh:mm a zzz"); - df.toLocalizedPattern(); - Date date = launchList.get(position).getNet(); - return parseDateToMMyyyy(df.format(date)); + return parseDateToMMyyyy(date); } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { @@ -215,11 +195,11 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL public ViewHolder(View view) { super(view); - categoryIcon = (ImageView) view.findViewById(R.id.categoryIcon); - title = (TextView) view.findViewById(R.id.launch_rocket); - location = (TextView) view.findViewById(R.id.location); - launch_date = (TextView) view.findViewById(R.id.launch_date); - mission = (TextView) view.findViewById(R.id.mission); + categoryIcon = view.findViewById(R.id.categoryIcon); + title = view.findViewById(R.id.launch_rocket); + location = view.findViewById(R.id.location); + launch_date = view.findViewById(R.id.launch_date); + mission = view.findViewById(R.id.mission); title.setOnClickListener(this); location.setOnClickListener(this); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java index d492c7667..3def8aec0 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/launches/PreviousLaunchesFragment.java @@ -56,6 +56,7 @@ import me.calebjones.spacelaunchnow.data.models.Constants; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.ui.main.MainActivity; +import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; import me.calebjones.spacelaunchnow.utils.views.SnackbarHandler; import timber.log.Timber; @@ -356,7 +357,7 @@ public void recreate() { private String formatDatesForTitle(String start_date) { SimpleDateFormat in = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat out = new SimpleDateFormat("LLL yyyy"); + SimpleDateFormat out = Utils.getSimpleDateFormatForUI("LLL yyyy"); Date sDate; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java index 625724975..49b598dd2 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/missions/MissionAdapter.java @@ -114,7 +114,7 @@ public void onBindViewHolder(final ViewHolder holder, int i) { //If we can find the date of the launch add it to the card. if (mission.getLaunch().getNet() != null) { - SimpleDateFormat outformat = new SimpleDateFormat("MMMM dd, yyyy"); + SimpleDateFormat outformat = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); outformat.toLocalizedPattern(); Date date; diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java index 1fbfdea43..44965ab65 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/next/CardAdapter.java @@ -11,6 +11,7 @@ import android.support.v4.app.ShareCompat; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; +import android.text.format.DateFormat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -30,6 +31,7 @@ import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.Locale; import java.util.TimeZone; import io.realm.RealmList; @@ -181,10 +183,10 @@ public boolean onPreDraw() { } if (launchItem.getProbability() != null && launchItem.getProbability() > 0) { - holder.contentForecast.setText(String.format("%s%%", launchItem.getProbability())); - holder.forecast_container.setVisibility(View.VISIBLE); + holder.contentForecast.setText(String.format("Weather Favorable: %s%%", launchItem.getProbability())); + holder.contentForecast.setVisibility(View.VISIBLE); } else { - holder.forecast_container.setVisibility(View.GONE); + holder.contentForecast.setVisibility(View.GONE); } switch (launchItem.getStatus()) { @@ -365,7 +367,8 @@ public void onTick(long millisUntilFinished) { if (launchItem.getNet() != null) { //Get launch date - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); + + SimpleDateFormat sdf = Utils.getSimpleDateFormatForUI("MMMM d, yyyy"); sdf.toLocalizedPattern(); Date date = launchItem.getNet(); String launchTime = sdf.format(date); @@ -401,7 +404,7 @@ public void onTick(long millisUntilFinished) { } else { launchTime = "To be determined... "; } - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); + SimpleDateFormat sdf = Utils.getSimpleDateFormatForUI("MMMM d, yyyy"); sdf.toLocalizedPattern(); Date date = launchItem.getNet(); holder.launch_date_compact.setText(sdf.format(date)); @@ -498,7 +501,6 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL public ImageView categoryIcon; public CountDownTimer timer; public View countdownView; - public View forecast_container; public TextView contentForecast; public ImageView map_view; @@ -528,7 +530,6 @@ public ViewHolder(View view) { countdownSeconds = view.findViewById(R.id.countdown_seconds); countdownView = view.findViewById(R.id.countdown_layout); - forecast_container = view.findViewById(R.id.forecast_container); contentForecast = view.findViewById(R.id.content_forecast); map_view = view.findViewById(R.id.map_view); @@ -549,7 +550,7 @@ public void onClick(View v) { final Launch launch = launchList.get(position); Intent sendIntent = new Intent(); - SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy - hh:mm a zzz"); + SimpleDateFormat df = Utils.getSimpleDateFormatForUI("EEEE, MMMM d, yyyy - hh:mm a zzz"); df.toLocalizedPattern(); Date date = launch.getNet(); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java index 55f6e968c..713dbfe85 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/AboutActivity.java @@ -88,7 +88,7 @@ public void onClick(View view) { @Override public void onInput(MaterialDialog dialog, CharSequence input) { // Do something - if(DebugAuthManager.getAuthResult(input)){ + if(!input.equals("") && DebugAuthManager.getAuthResult(input)){ goToDebug(); } else { Toast.makeText(context, "Error - Support code was not correct.", Toast.LENGTH_LONG).show(); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java index 4cdd760d6..e8bba129c 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/settings/fragments/AppearanceFragment.java @@ -40,6 +40,7 @@ public class AppearanceFragment extends BaseSettingFragment implements SharedPre private ColorPreference widgetAccentColor; private ColorPreference widgetTitleColor; private SwitchPreference widgetRoundCorners; + private SwitchPreference widgetHideSettings; private boolean isCustomColor = false; private int[] textPrimaryArray; private int[] textSecondaryArray; @@ -127,7 +128,7 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin Analytics.from(this).sendPreferenceEvent(key); } - if (key.equals("widget_background_color") || key.equals("widget_text_color") || key.equals("widget_secondary_text_color") || key.equals("widget_icon_color") || key.equals("widget_title_text_color") || key.equals("widget_list_accent_color")) { + if (key.equals("widget_background_color") || key.equals("widget_text_color") || key.equals("widget_secondary_text_color") || key.equals("widget_icon_color") || key.equals("widget_title_text_color") || key.equals("widget_list_accent_color") || key.equals("widget_refresh_enabled")) { Intent nextIntent = new Intent(context, WidgetBroadcastReceiver.class); nextIntent.putExtra("updateUIOnly", true); context.sendBroadcast(nextIntent); @@ -178,6 +179,7 @@ private void setupPreferences() { widgetRoundCorners = (SwitchPreference) findPreference("widget_theme_round_corner"); widgetAccentColor = (ColorPreference) findPreference("widget_list_accent_color"); widgetTitleColor = (ColorPreference) findPreference("widget_title_text_color"); + widgetHideSettings = (SwitchPreference) findPreference("widget_refresh_enabled"); if (!SupporterHelper.isSupporter()) { Preference weather = findPreference("weather"); weather.setEnabled(false); @@ -216,6 +218,9 @@ private void setupPreferences() { widgetTitleColor.setEnabled(false); widgetTitleColor.setSelectable(false); + + widgetHideSettings.setEnabled(false); + widgetHideSettings.setSelectable(false); } Preference localTime = findPreference("local_time"); localTime.setOnPreferenceChangeListener(createLocalTimeListener()); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java index 43ce49b0f..ec9117eda 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/utils/Utils.java @@ -33,6 +33,7 @@ import android.os.Build; import android.support.customtabs.CustomTabsIntent; import android.support.v4.content.ContextCompat; +import android.text.format.DateFormat; import android.view.View; import android.view.ViewPropertyAnimator; import android.view.animation.PathInterpolator; @@ -604,5 +605,10 @@ public static Bitmap getBitMapFromUrl(Context context, String imageURL) { return null; } } + + public static SimpleDateFormat getSimpleDateFormatForUI(String pattern) { + String format = DateFormat.getBestDateTimePattern(Locale.getDefault(), pattern); + return new SimpleDateFormat(format, Locale.getDefault()); + } } diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java index 8294fb3c1..187507f9f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchcard/LaunchCardCompactManager.java @@ -6,8 +6,10 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; +import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.view.View; import android.widget.RemoteViews; import java.text.SimpleDateFormat; @@ -119,6 +121,8 @@ private void setRefreshIntent(Launch launch) { Intent exploreIntent = new Intent(context, LaunchDetailActivity.class); exploreIntent.putExtra("TYPE", "launch"); exploreIntent.putExtra("launchID", launch.getId()); + exploreIntent.setData(Uri.parse(exploreIntent.toUri(Intent.URI_INTENT_SCHEME))); + exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent actionPendingIntent = PendingIntent.getActivity(context, UniqueIdentifier.getID(), exploreIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.widget_compact_card_frame, actionPendingIntent); @@ -152,6 +156,11 @@ private void setWidgetStyle() { remoteViews.setTextColor(R.id.widget_launch_date, widgetSecondaryTextColor); remoteViews.setInt(R.id.widget_categoryIcon, "setColorFilter", widgetIconColor); remoteViews.setInt(R.id.widget_compact_card_refresh_button, "setColorFilter", widgetIconColor); + if (sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_compact_card_refresh_button, View.GONE); + } else if (!sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_compact_card_refresh_button, View.VISIBLE); + } } private void setLocationName(Launch launchRealm) { @@ -195,9 +204,9 @@ private void setLaunchName(Launch launchRealm) { private void setLaunchDate(Launch launch) { SimpleDateFormat sdf; if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("MMMM dd, yyyy"); + sdf = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); } else { - sdf = new SimpleDateFormat("MMMM dd, yyyy"); + sdf = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); } sdf.toLocalizedPattern(); if (launch.getNet() != null) { diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java index 956ff45cc..5c356c5f5 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListFactory.java @@ -6,6 +6,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; +import android.net.Uri; import android.preference.PreferenceManager; import android.widget.RemoteViews; import android.widget.RemoteViewsService; @@ -118,7 +119,7 @@ public RemoteViews getViewAt(int position) { RemoteViews row = new RemoteViews(context.getPackageName(), R.layout.launch_list_item); String[] title; String launchDate; - SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy"); + SimpleDateFormat sdf = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); //Retrieve missionType if (launch.getMissions().size() != 0) { @@ -186,8 +187,8 @@ public RemoteViews getViewAt(int position) { Intent exploreIntent = new Intent(context, LaunchDetailActivity.class); exploreIntent.putExtra("TYPE", "launch"); exploreIntent.putExtra("launchID", launch.getId()); - exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - + exploreIntent.setData(Uri.parse(exploreIntent.toUri(Intent.URI_INTENT_SCHEME))); + exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); row.setOnClickFillInIntent(R.id.rootview, exploreIntent); return (row); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java index 5ef3cd0c9..fbf3baf62 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/launchlist/LaunchListManager.java @@ -8,11 +8,13 @@ import android.graphics.Color; import android.net.Uri; import android.preference.PreferenceManager; +import android.view.View; import android.widget.RemoteViews; import me.calebjones.spacelaunchnow.R; import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.ui.main.MainActivity; +import me.calebjones.spacelaunchnow.ui.supporter.SupporterActivity; import me.calebjones.spacelaunchnow.ui.supporter.SupporterHelper; import me.calebjones.spacelaunchnow.utils.UniqueIdentifier; import me.calebjones.spacelaunchnow.widget.WidgetBroadcastReceiver; @@ -55,7 +57,7 @@ private void buildSupporterWidget(int appWidgetId) { int widgetIconsColor = sharedPref.getInt("widget_icon_color", colorWhite); if (sharedPref.getBoolean("widget_theme_round_corner", true)) { - remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded); + remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded_bottom); remoteViews.setImageViewResource(R.id.title_background, R.drawable.rounded_top); } else { remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.squared); @@ -70,6 +72,7 @@ private void buildSupporterWidget(int appWidgetId) { remoteViews.setInt(R.id.bgcolor, "setColorFilter", Color.rgb(red,green,blue)); remoteViews.setInt(R.id.bgcolor, "setAlpha", widgetAlpha); + widgetAlpha = Color.alpha(widgetAccentColor); red = Color.red(widgetAccentColor); green = Color.green(widgetAccentColor); blue = Color.blue(widgetAccentColor); @@ -92,6 +95,12 @@ private void buildSupporterWidget(int appWidgetId) { remoteViews.setOnClickPendingIntent(R.id.title, actionPendingIntent); + Intent supportIntent = new Intent(context, SupporterActivity.class); + supportIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + PendingIntent supportPendingIntent = PendingIntent.getActivity(context, 0, supportIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + remoteViews.setOnClickPendingIntent(R.id.supporter_message, supportPendingIntent); + appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } @@ -114,7 +123,7 @@ private void buildWidget(int appWidgetId) { int widgetIconsColor = sharedPref.getInt("widget_icon_color", colorWhite); if (sharedPref.getBoolean("widget_theme_round_corner", true)) { - remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded); + remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.rounded_bottom); remoteViews.setImageViewResource(R.id.title_background, R.drawable.rounded_top); } else { remoteViews.setImageViewResource(R.id.bgcolor, R.drawable.squared); @@ -129,6 +138,7 @@ private void buildWidget(int appWidgetId) { remoteViews.setInt(R.id.bgcolor, "setColorFilter", Color.rgb(red,green,blue)); remoteViews.setInt(R.id.bgcolor, "setAlpha", widgetAlpha); + widgetAlpha = Color.alpha(widgetAccentColor); red = Color.red(widgetAccentColor); green = Color.green(widgetAccentColor); blue = Color.blue(widgetAccentColor); @@ -148,6 +158,12 @@ private void buildWidget(int appWidgetId) { PendingIntent refreshPending = PendingIntent.getBroadcast(context, 0, nextIntent, 0); remoteViews.setOnClickPendingIntent(R.id.widget_refresh_button, refreshPending); + if (sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_refresh_button, View.GONE); + } else if (!sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_refresh_button, View.VISIBLE); + } + Intent openAppIntent = new Intent(context, MainActivity.class); openAppIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent actionPendingIntent = PendingIntent.getActivity(context, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java index 2f19403c0..87e2605ad 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/widget/wordtimer/LaunchWordTimerManager.java @@ -6,8 +6,10 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; +import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.view.View; import android.widget.RemoteViews; import java.text.SimpleDateFormat; @@ -120,7 +122,8 @@ private void setRefreshIntent(Launch launch) { Intent exploreIntent = new Intent(context, LaunchDetailActivity.class); exploreIntent.putExtra("TYPE", "launch"); exploreIntent.putExtra("launchID", launch.getId()); - exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + exploreIntent.setData(Uri.parse(exploreIntent.toUri(Intent.URI_INTENT_SCHEME))); + exploreIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent actionPendingIntent = PendingIntent.getActivity(context, UniqueIdentifier.getID(), exploreIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.widget_countdown_timer_frame, actionPendingIntent); @@ -181,6 +184,11 @@ private void setWidgetStyle() { remoteViews.setTextColor(R.id.countdown_hours_label, widgetSecondaryTextColor); remoteViews.setInt(R.id.widget_refresh_button, "setColorFilter", widgetIconColor); + if (sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_refresh_button, View.GONE); + } else if (!sharedPref.getBoolean("widget_refresh_enabled", false)) { + remoteViews.setViewVisibility(R.id.widget_refresh_button, View.VISIBLE); + } } private void setLaunchName(Launch launchRealm) { @@ -193,21 +201,6 @@ private void setLaunchName(Launch launchRealm) { } } - private void setLaunchDate(Launch launch) { - SimpleDateFormat sdf; - if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("24_hour_mode", false)) { - sdf = new SimpleDateFormat("MMMM dd, yyyy"); - } else { - sdf = new SimpleDateFormat("MMMM dd, yyyy"); - } - sdf.toLocalizedPattern(); - if (launch.getNet() != null) { - remoteViews.setTextViewText(R.id.widget_launch_date, sdf.format(launch.getNet())); - } else { - remoteViews.setTextViewText(R.id.widget_launch_date, "Unknown Launch Date"); - } - } - private String getLaunchName(Launch launchRealm) { //Replace with launch if (launchRealm.getRocket() != null && launchRealm.getRocket().getName() != null) { diff --git a/mobile/src/main/res/drawable/rounded_bottom.xml b/mobile/src/main/res/drawable/rounded_bottom.xml new file mode 100644 index 000000000..a54f6910b --- /dev/null +++ b/mobile/src/main/res/drawable/rounded_bottom.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/mobile/src/main/res/layout-w500dp/content_card_item.xml b/mobile/src/main/res/layout-w500dp/content_card_item.xml index a9ee3fa33..8bdaadd33 100644 --- a/mobile/src/main/res/layout-w500dp/content_card_item.xml +++ b/mobile/src/main/res/layout-w500dp/content_card_item.xml @@ -170,61 +170,39 @@ android:textAppearance="@style/MaterialTypography.Regular.Subheading" android:textColor="?android:textColorSecondary" /> + + + android:orientation="vertical"> - - - - - - - - @@ -233,9 +211,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="8dp" - android:paddingLeft="28dp" - android:paddingRight="28dp" android:paddingTop="8dp" + android:layout_marginStart="@dimen/material_baseline_grid_2.5x" + android:layout_marginEnd="@dimen/material_baseline_grid_2.5x" android:textColor="?android:textColorSecondary" android:textSize="14sp" /> @@ -243,37 +221,28 @@ + android:text="Watch Live" /> + android:layout_alignParentEnd="true" + android:layout_marginEnd="@dimen/material_baseline_grid_2x" + android:text="Share" /> + android:text="Explore" /> diff --git a/mobile/src/main/res/layout-w500dp/detail_launch_summary.xml b/mobile/src/main/res/layout-w500dp/detail_launch_summary.xml index 64f0288a1..83ddbbe3e 100644 --- a/mobile/src/main/res/layout-w500dp/detail_launch_summary.xml +++ b/mobile/src/main/res/layout-w500dp/detail_launch_summary.xml @@ -16,6 +16,25 @@ android:layout_height="fill_parent" android:orientation="vertical"> + + + + + + + android:text="Launch Window" + android:textAlignment="center" + android:textAppearance="@style/MaterialTypography.Regular.Subheading" /> diff --git a/mobile/src/main/res/layout/activity_launch_detail.xml b/mobile/src/main/res/layout/activity_launch_detail.xml index 7534a7389..8a860d944 100644 --- a/mobile/src/main/res/layout/activity_launch_detail.xml +++ b/mobile/src/main/res/layout/activity_launch_detail.xml @@ -10,6 +10,7 @@ android:id="@+id/detail.appbar" android:layout_width="match_parent" android:layout_height="wrap_content" + android:elevation="8dp" android:fitsSystemWindows="true"> + android:elevation="8dp"> + android:elevation="8dp" + app:popupTheme="@style/AppTheme.PopupOverlay"/> @@ -31,6 +32,7 @@ android:id="@+id/irr_layout" style="@style/SPL.SnackBar.Layout" android:visibility="gone" + android:elevation="8dp" irr:autoEvaluateDefaultRuleEngine="true" irr:defaultRuleAppStartCount="10" irr:defaultRuleDismissMaxCount="3" @@ -44,6 +46,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" + android:elevation="8dp" tools:visibility="visible"> @@ -106,13 +106,13 @@ android:id="@+id/content_status" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/titleBarColor" android:ellipsize="end" android:gravity="center" android:paddingBottom="8dp" android:paddingTop="4dp" android:singleLine="false" android:text="Unknown Launch Status" - android:background="?attr/titleBarColor" android:textAlignment="center" android:textColor="@color/dark_primary_text_color_selector" android:textSize="20sp" @@ -125,7 +125,6 @@ android:orientation="vertical"> - + + + android:orientation="vertical"> - - - - - - - - @@ -233,9 +211,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="8dp" - android:paddingLeft="28dp" - android:paddingRight="28dp" android:paddingTop="8dp" + android:layout_marginStart="@dimen/material_baseline_grid_2.5x" + android:layout_marginEnd="@dimen/material_baseline_grid_2.5x" android:textColor="?android:textColorSecondary" android:textSize="14sp" /> @@ -243,37 +221,28 @@ + android:text="Watch Live" /> + android:layout_alignParentEnd="true" + android:layout_marginEnd="@dimen/material_baseline_grid_2x" + android:text="Share" /> + android:text="Explore" /> diff --git a/mobile/src/main/res/layout/detail_launch_summary.xml b/mobile/src/main/res/layout/detail_launch_summary.xml index a66d21d4e..89be13ff3 100644 --- a/mobile/src/main/res/layout/detail_launch_summary.xml +++ b/mobile/src/main/res/layout/detail_launch_summary.xml @@ -1,6 +1,5 @@ - + + + + + + + + + + + + @@ -113,8 +155,8 @@ android:paddingTop="8dp" android:text="Estimated Launch Date" android:textAlignment="center" - android:textSize="18sp" - android:textAppearance="@style/MaterialTypography.Regular.Subheading"/> + android:textAppearance="@style/MaterialTypography.Regular.Subheading" + android:textSize="18sp" /> + android:text="Launch Window" + android:textAlignment="center" + android:textAppearance="@style/MaterialTypography.Regular.Subheading" /> - diff --git a/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml b/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml index 624852813..14ad44bc0 100644 --- a/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml +++ b/mobile/src/main/res/layout/widget_launch_card_compact_large_dark.xml @@ -29,14 +29,14 @@ android:layout_gravity="center" android:padding="@dimen/material_baseline_grid_0.5x" android:layout_marginStart="@dimen/material_baseline_grid_1x" - android:layout_marginEnd="@dimen/material_baseline_grid_1x" + android:layout_marginEnd="@dimen/material_baseline_grid_0.5x" android:src="@drawable/ic_unknown_white" /> - - - + android:layout_height="match_parent"> + + + + + + \ No newline at end of file diff --git a/mobile/src/main/res/values/colors.xml b/mobile/src/main/res/values/colors.xml index 801a3e928..0472bf945 100644 --- a/mobile/src/main/res/values/colors.xml +++ b/mobile/src/main/res/values/colors.xml @@ -1,11 +1,11 @@ - #42a5f5 - #1E88E5 - #1e88e5 - #2962ff + #2196F3 + #1976D2 + #1976D2 + #BBDEFB #42a5f5 - #ef5350 + #FF5252 #05A8AA #f44336 #212121 diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index 3f58bec52..d1ea161b7 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -60,4 +60,7 @@ Get to know the vehicles that have taken us to orbit. http://res.cloudinary.com/dnkkbfy3m/image/upload/v1462465326/navbar_one_sqfhes.png This application, Space Launch Now, started as a simple weekend project. In the course of a year its grown to nearly 10,000 active users. I am incredibly appreciative to everyone that has taken the time to report bugs, give feedback, participate in BETA\'s and become supporters. + Error initializing YouTube player: %s + Jump To + Seconds diff --git a/mobile/src/main/res/xml/appearance_preferences.xml b/mobile/src/main/res/xml/appearance_preferences.xml index f3acccefe..d5c495583 100644 --- a/mobile/src/main/res/xml/appearance_preferences.xml +++ b/mobile/src/main/res/xml/appearance_preferences.xml @@ -68,8 +68,8 @@ + Date: Wed, 3 Jan 2018 13:48:29 -0500 Subject: [PATCH 30/41] this one too --- .../fragments/SummaryDetailFragment.java | 265 +++++++++++++----- 1 file changed, 195 insertions(+), 70 deletions(-) diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java index 34710bd6b..ab1755e3f 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/launchdetail/fragments/SummaryDetailFragment.java @@ -10,6 +10,7 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentTransaction; import android.support.v4.content.ContextCompat; import android.support.v4.widget.NestedScrollView; import android.support.v7.widget.AppCompatButton; @@ -30,18 +31,28 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.simplelist.MaterialSimpleListItem; +import com.crashlytics.android.Crashlytics; import com.github.pwittchen.weathericonview.WeatherIconView; +import com.google.android.youtube.player.YouTubeInitializationResult; +import com.google.android.youtube.player.YouTubePlayer; +import com.google.android.youtube.player.YouTubePlayerSupportFragment; import com.mypopsy.maps.StaticMap; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; +import org.w3c.dom.Text; +import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.Locale; import java.util.TimeZone; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import butterknife.BindView; import butterknife.ButterKnife; @@ -54,15 +65,16 @@ import me.calebjones.spacelaunchnow.content.database.ListPreferences; import me.calebjones.spacelaunchnow.content.database.SwitchPreferences; import me.calebjones.spacelaunchnow.content.events.LaunchEvent; -import me.calebjones.spacelaunchnow.content.services.LibraryDataManager; import me.calebjones.spacelaunchnow.content.util.DialogAdapter; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Launch; import me.calebjones.spacelaunchnow.data.models.launchlibrary.Pad; -import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; import me.calebjones.spacelaunchnow.data.models.realm.RealmStr; +import me.calebjones.spacelaunchnow.data.models.spacelaunchnow.RocketDetail; +import me.calebjones.spacelaunchnow.ui.launchdetail.activity.LaunchDetailActivity; import me.calebjones.spacelaunchnow.utils.GlideApp; import me.calebjones.spacelaunchnow.utils.Utils; import me.calebjones.spacelaunchnow.utils.analytics.Analytics; +import me.calebjones.spacelaunchnow.utils.analytics.CrashlyticsTree; import me.calebjones.spacelaunchnow.utils.views.CountDownTimer; import retrofit2.Call; import retrofit2.Callback; @@ -78,8 +90,9 @@ public class SummaryDetailFragment extends BaseFragment { private CountDownTimer timer; public Launch detailLaunch; private RocketDetail launchVehicle; - + private YouTubePlayerSupportFragment youTubePlayerFragment; private boolean nightMode; + private String youTubeURL; @BindView(R.id.content_TMinus_status) TextView contentTMinusStatus; @@ -107,10 +120,6 @@ public class SummaryDetailFragment extends BaseFragment { TextView launch_date_title; @BindView(R.id.date) TextView date; - @BindView(R.id.launch_window_start) - TextView launch_window_start; - @BindView(R.id.launch_window_end) - TextView launch_window_end; @BindView(R.id.launch_status) TextView launch_status; @BindView(R.id.watchButton) @@ -183,11 +192,21 @@ public class SummaryDetailFragment extends BaseFragment { WeatherIconView weatherPrecipIcon; @BindView(R.id.weather_wind_speed_icon) WeatherIconView weatherSpeedIcon; + @BindView(R.id.launch_window_title) + TextView launchWindowTitle; + @BindView(R.id.launch_window_text) + TextView launchWindowText; + @BindView(R.id.youtube_card) + CardView youtubeCard; + @BindView(R.id.error_message) + TextView errorMessage; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setScreenName("Summary Detail Fragment"); + // retain this fragment + setRetainInstance(true); } @Override @@ -206,6 +225,10 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa View view = inflater.inflate(R.layout.detail_launch_summary, container, false); ButterKnife.bind(this, view); + youTubePlayerFragment = YouTubePlayerSupportFragment.newInstance(); + FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); + transaction.add(R.id.youtube_view, youTubePlayerFragment).commit(); + return view; } @@ -573,7 +596,7 @@ public boolean onPreDraw() { //Setup SimpleDateFormat to parse out getNet date. SimpleDateFormat input = new SimpleDateFormat("MMMM dd, yyyy hh:mm:ss zzz"); - SimpleDateFormat output = new SimpleDateFormat("MMMM dd, yyyy"); + SimpleDateFormat output = Utils.getSimpleDateFormatForUI("MMMM dd, yyyy"); input.toLocalizedPattern(); Date mDate; @@ -622,6 +645,130 @@ public void execute(Realm realm) { }); if (detailLaunch.getVidURLs() != null && detailLaunch.getVidURLs().size() > 0) { + + final String regex = "(youtu\\.be\\/|youtube\\.com\\/(watch\\?(.*&)?v=|(embed|v)\\/|c\\/))([^\\?&\"'>].*)"; + final Pattern pattern = Pattern.compile(regex); + + for (RealmStr url: detailLaunch.getVidURLs()){ + Matcher matcher = pattern.matcher(url.getVal()); + Timber.v("Checking for match of %s", url.getVal()); + if (matcher.find() && (matcher.group(1) != null || matcher.group(2) != null) && matcher.group(5) != null) { + youTubeURL = matcher.group(5); + break; + } + } + + if (youTubeURL != null) { + youtubeCard.setVisibility(View.VISIBLE); + final LaunchDetailActivity mainActivity = (LaunchDetailActivity) getActivity(); + youTubePlayerFragment.initialize(context.getResources().getString(R.string.GoogleMapsKey), new YouTubePlayer.OnInitializedListener() { + @Override + public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean restored) { + mainActivity.youTubePlayer = youTubePlayer; + youTubePlayer.cueVideo(youTubeURL); + youTubePlayer.setOnFullscreenListener(new YouTubePlayer.OnFullscreenListener() { + @Override + public void onFullscreen(boolean b) { + mainActivity.isYouTubePlayerFullScreen = b; + } + }); + youTubePlayer.setPlaybackEventListener(new YouTubePlayer.PlaybackEventListener() { + @Override + public void onPlaying() { + Timber.v("onPlaying"); + } + + @Override + public void onPaused() { + Timber.v("onPaused"); + } + + @Override + public void onStopped() { + Timber.v("onStopped"); + } + + @Override + public void onBuffering(boolean b) { + Timber.v("onBuffering %s", b); + } + + @Override + public void onSeekTo(int i) { + Timber.v("onSeekTo %s", i); + } + }); + youTubePlayer.setPlaylistEventListener(new YouTubePlayer.PlaylistEventListener() { + @Override + public void onPrevious() { + Timber.v("onPrevious"); + } + + @Override + public void onNext() { + Timber.v("onNext"); + } + + @Override + public void onPlaylistEnded() { + Timber.v("onPlaylistEnded"); + } + }); + youTubePlayer.setPlayerStateChangeListener(new YouTubePlayer.PlayerStateChangeListener() { + @Override + public void onLoading() { + Timber.v("onLoading"); + } + + @Override + public void onLoaded(String s) { + Timber.v("onLoaded %s", s); + if (youTubeURL.contains("live")) { + errorMessage.setVisibility(View.VISIBLE); + errorMessage.setText(String.format("Live Broadcast %s", s)); + } + } + + @Override + public void onAdStarted() { + Timber.v("onAdStarted"); + } + + @Override + public void onVideoStarted() { + Timber.v("onVideoStarted"); + } + + @Override + public void onVideoEnded() { + Timber.v("onVideoEnded"); + } + + @Override + public void onError(YouTubePlayer.ErrorReason errorReason) { + Timber.v("onError - %s", errorReason.name()); + if (youTubeURL.contains("live")) { + errorMessage.setVisibility(View.VISIBLE); + errorMessage.setText("Broadcast may not be live."); + } + Crashlytics.log(errorReason.name()); + } + }); + + } + + @Override + public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) { + if (youTubeInitializationResult.isUserRecoverableError()) { + youTubeInitializationResult.getErrorDialog(getActivity(), 1).show(); + } else { + String error = String.format(getString(R.string.player_error), youTubeInitializationResult.toString()); + Toast.makeText(getContext(), error, Toast.LENGTH_LONG).show(); + } + } + }); + } + watchButton.setVisibility(View.VISIBLE); watchButton.setOnClickListener(new View.OnClickListener() { @Override @@ -674,11 +821,11 @@ public void onListItemSelected(int index, MaterialSimpleListItem item, boolean l date.setText(dateText); - if (detailLaunch.getWsstamp() > 0 && detailLaunch.getWestamp() > 0) { + if (detailLaunch.getWindowstart() != null && detailLaunch.getWindowstart() != null) { setWindowStamp(); } else { - launch_window_start.setVisibility(View.GONE); - launch_window_end.setVisibility(View.GONE); + launchWindowTitle.setVisibility(View.GONE); + launchWindowText.setVisibility(View.GONE); } } catch (NullPointerException e) { Timber.e(e); @@ -883,64 +1030,47 @@ private void getLaunchVehicle(Launch vehicle) { private void setWindowStamp() { // Create a DateFormatter object for displaying date in specified format. - SimpleDateFormat formatter; - if (sharedPref.getBoolean("24_hour_mode", false)) { - formatter = new SimpleDateFormat("HH:mm zzz"); - } else { - formatter = new SimpleDateFormat("hh:mm a zzz"); - } - // Create a calendar object that will convert the date and time value in milliseconds to date. - Calendar calendarStart = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - long startDate = detailLaunch.getWsstamp(); - startDate = startDate * 1000; - calendarStart.setTimeInMillis(startDate); - String start = formatter.format(calendarStart.getTime()); - - // Create a calendar object that will convert the date and time value in milliseconds to date. - Calendar calendarEnd = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - long endDate = detailLaunch.getWestamp(); - endDate = endDate * 1000; - calendarEnd.setTimeInMillis(endDate); - String end = formatter.format(calendarEnd.getTime()); - - if (!start.equals(end)) { - if (start.length() == 0 - || end.length() == 0) { - launch_window_start.setText(String.format("Launch Time: %s", - start)); - launch_window_end.setVisibility(View.GONE); - } else { - launch_window_start.setText(String.format("Window Start: %s", - start)); - launch_window_end.setVisibility(View.VISIBLE); - launch_window_end.setText(String.format("Window End: %s", - end)); + Date windowStart = detailLaunch.getWindowstart(); + Date windowEnd = detailLaunch.getWindowend(); + + boolean twentyFourHourMode = sharedPref.getBoolean("24_hour_mode", false); + DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()); + + if (windowStart.equals(windowEnd)) { + // Window Start and Window End match - meaning instantaneous. + if (twentyFourHourMode) { + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } - } else { - launch_window_start.setText(String.format("Launch Time: %s", - start)); - launch_window_end.setVisibility(View.GONE); - } - } - private void setWindowStartEnd() { - if (!detailLaunch.getWindowstart().equals(detailLaunch.getWindowend())) { - if (detailLaunch.getWindowstart().toString().length() > 0 - || detailLaunch.getWindowend().toString().length() > 0) { - launch_window_start.setText("Launch Window unavailable."); - launch_window_end.setVisibility(View.INVISIBLE); - } else { - launch_window_start.setText(String.format("Window Start: %s", - detailLaunch.getWindowstart())); - launch_window_end.setVisibility(View.VISIBLE); - launch_window_end.setText(String.format("Window End: %s", - detailLaunch.getWindowend())); + TimeZone timeZone = dateFormat.getTimeZone(); + launchWindowTitle.setText("Launch Window"); + launchWindowText.setText(String.format("%s %s", + dateFormat.format(windowStart), + timeZone.getDisplayName(false, TimeZone.SHORT))); + } else if (windowStart.after(windowEnd)) { + // Launch data is not trustworthy - start is after end. + if (twentyFourHourMode) { + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } - } else { - launch_window_start.setText(String.format("Launch Time: %s", - detailLaunch.getWindowstart())); - launch_window_end.setVisibility(View.INVISIBLE); + + TimeZone timeZone = dateFormat.getTimeZone(); + launchWindowTitle.setText("Launch Window"); + launchWindowText.setText(String.format("%s %s", + dateFormat.format(windowStart), + timeZone.getDisplayName(false, TimeZone.SHORT))); + } else if (windowStart.before(windowEnd)) { + // Launch Window is properly configured + if (twentyFourHourMode) { + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + TimeZone timeZone = dateFormat.getTimeZone(); + launchWindowTitle.setText("Launch Window"); + launchWindowText.setText(String.format("%s - %s %s", + dateFormat.format(windowStart), + dateFormat.format(windowEnd), + timeZone.getDisplayName(false, TimeZone.SHORT))); } } @@ -970,11 +1100,6 @@ public void onStop() { super.onStop(); } - @Override - public void onDestroyView() { - super.onDestroyView(); - } - @OnClick(R.id.map_view_summary) public void onViewClicked() { String location = detailLaunch.getLocation().getName(); From c36ae214c6a7bab156d2c253f2c7485e3bc06c8a Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Thu, 4 Jan 2018 08:49:12 -0500 Subject: [PATCH 31/41] WIP rating needs replaced. --- build.gradle | 2 +- mobile/src/main/AndroidManifest.xml | 1 + .../spacelaunchnow/LaunchApplication.java | 4 - .../activity/LaunchDetailActivity.java | 32 +- .../fragments/SummaryDetailFragment.java | 277 +++++++++--------- .../spacelaunchnow/ui/main/MainActivity.java | 23 ++ .../fragment_launches_view_pager.xml | 4 +- .../res/layout-w500dp/content_card_item.xml | 4 + .../layout-w500dp/detail_launch_summary.xml | 140 ++++----- mobile/src/main/res/layout/activity_main.xml | 52 ++-- mobile/src/main/res/layout/app_bar_main.xml | 112 +------ .../src/main/res/layout/content_card_item.xml | 8 + .../main/res/layout/detail_launch_summary.xml | 122 +++----- .../layout/fragment_launches_view_pager.xml | 4 + 14 files changed, 349 insertions(+), 436 deletions(-) diff --git a/build.gradle b/build.gradle index 057e377f9..84747a220 100644 --- a/build.gradle +++ b/build.gradle @@ -46,7 +46,7 @@ ext { buildToolsVersion = '23.0.3' // App dependencies - supportLibraryVersion = '27.0.1' + supportLibraryVersion = '27.0.2' playServicesVersion = '11.6.0' sdk = 25 diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml index 5a33eac16..29250e9ea 100644 --- a/mobile/src/main/AndroidManifest.xml +++ b/mobile/src/main/AndroidManifest.xml @@ -58,6 +58,7 @@ 0) { - final String regex = "(youtu\\.be\\/|youtube\\.com\\/(watch\\?(.*&)?v=|(embed|v)\\/|c\\/))([^\\?&\"'>].*)"; - final Pattern pattern = Pattern.compile(regex); - - for (RealmStr url: detailLaunch.getVidURLs()){ - Matcher matcher = pattern.matcher(url.getVal()); - Timber.v("Checking for match of %s", url.getVal()); - if (matcher.find() && (matcher.group(1) != null || matcher.group(2) != null) && matcher.group(5) != null) { - youTubeURL = matcher.group(5); - break; - } + for (RealmStr url : detailLaunch.getVidURLs()) { + youTubeURL = getYouTubeID(url.getVal()); + if (youTubeURL != null) break; } if (youTubeURL != null) { - youtubeCard.setVisibility(View.VISIBLE); + mapView.setVisibility(View.GONE); + youTubeViewHolder.setVisibility(View.VISIBLE); final LaunchDetailActivity mainActivity = (LaunchDetailActivity) getActivity(); youTubePlayerFragment.initialize(context.getResources().getString(R.string.GoogleMapsKey), new YouTubePlayer.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean restored) { mainActivity.youTubePlayer = youTubePlayer; - youTubePlayer.cueVideo(youTubeURL); + summaryYouTubePlayer = youTubePlayer; + if (!restored) { + youTubePlayer.cueVideo(youTubeURL); + } youTubePlayer.setOnFullscreenListener(new YouTubePlayer.OnFullscreenListener() { @Override public void onFullscreen(boolean b) { @@ -676,16 +652,19 @@ public void onFullscreen(boolean b) { @Override public void onPlaying() { Timber.v("onPlaying"); + mainActivity.videoPlaying(); } @Override public void onPaused() { Timber.v("onPaused"); + mainActivity.videoStopped(); } @Override public void onStopped() { Timber.v("onStopped"); + mainActivity.videoStopped(); } @Override @@ -751,6 +730,9 @@ public void onError(YouTubePlayer.ErrorReason errorReason) { errorMessage.setVisibility(View.VISIBLE); errorMessage.setText("Broadcast may not be live."); } + if (errorReason.ordinal() == 4){ + Toast.makeText(mainActivity, "YouTube API is weird - pauses video when a view overlaps it.", Toast.LENGTH_SHORT).show(); + } Crashlytics.log(errorReason.name()); } }); @@ -786,12 +768,21 @@ public void onListItemSelected(int index, MaterialSimpleListItem item, boolean l sendIntent.setType("text/plain"); context.startActivity(sendIntent); } else { - Uri watchUri = Uri.parse(detailLaunch.getVidURLs().get(index).getVal()); - Intent i = new Intent(Intent.ACTION_VIEW, watchUri); - context.startActivity(i); + String url = detailLaunch.getVidURLs().get(index).getVal(); + String youTubeID = getYouTubeID(url); + if (summaryYouTubePlayer != null && youTubeID != null){ + if (dialog != null && dialog.isShowing()) dialog.dismiss(); + summaryYouTubePlayer.cueVideo(youTubeID); + summaryYouTubePlayer.play(); + } else { + Uri watchUri = Uri.parse(url); + Intent i = new Intent(Intent.ACTION_VIEW, watchUri); + context.startActivity(i); + } } } }); + for (RealmStr s : detailLaunch.getVidURLs()) { //Do your stuff here adapter.add(new MaterialSimpleListItem.Builder(context) @@ -804,7 +795,7 @@ public void onListItemSelected(int index, MaterialSimpleListItem item, boolean l .content("Long press for additional options.") .adapter(adapter, null) .negativeText("Cancel"); - builder.show(); + dialog = builder.show(); } } }); @@ -824,7 +815,6 @@ public void onListItemSelected(int index, MaterialSimpleListItem item, boolean l if (detailLaunch.getWindowstart() != null && detailLaunch.getWindowstart() != null) { setWindowStamp(); } else { - launchWindowTitle.setVisibility(View.GONE); launchWindowText.setVisibility(View.GONE); } } catch (NullPointerException e) { @@ -832,6 +822,18 @@ public void onListItemSelected(int index, MaterialSimpleListItem item, boolean l } } + private String getYouTubeID(String vidURL) { + final String regex = "(youtu\\.be\\/|youtube\\.com\\/(watch\\?(.*&)?v=|(embed|v)\\/|c\\/))([^\\?&\"'>].*)"; + final Pattern pattern = Pattern.compile(regex); + + Matcher matcher = pattern.matcher(vidURL); + Timber.v("Checking for match of %s", vidURL); + if (matcher.find() && (matcher.group(1) != null || matcher.group(2) != null) && matcher.group(5) != null) { + return matcher.group(5); + } + return null; + } + private void setupCountdownTimer(Launch launch) { //If timestamp is available calculate TMinus and date. if (launch.getNetstamp() > 0) { @@ -858,107 +860,113 @@ private void setupCountdownTimer(Launch launch) { contentTMinusStatus.setTypeface(Typeface.SANS_SERIF); contentTMinusStatus.setTextColor(accentColor); - countdownLayout.setVisibility(View.VISIBLE); - long timeToFinish = future.getTimeInMillis() - now.getTimeInMillis(); - timer = new CountDownTimer(timeToFinish, 1000) { - StringBuilder time = new StringBuilder(); - - @Override - public void onFinish() { - Timber.v("Countdown finished."); - contentTMinusStatus.setTypeface(Typeface.DEFAULT); - if (sharedPreference.isNightModeActive(context)) { - contentTMinusStatus.setTextColor(nightColor); - } else { - contentTMinusStatus.setTextColor(color); - } - if (status == 1) { - contentTMinusStatus.setText("Watch Live webcast for up to date status."); + if (detailLaunch.getStatus() == 3 || detailLaunch.getStatus() == 4) { + countdownLayout.setVisibility(View.GONE); + countdownSeparator.setVisibility(View.GONE); + contentTMinusStatus.setVisibility(View.GONE); + } else { + countdownLayout.setVisibility(View.VISIBLE); + long timeToFinish = future.getTimeInMillis() - now.getTimeInMillis(); + timer = new CountDownTimer(timeToFinish, 1000) { + StringBuilder time = new StringBuilder(); - } else { - if (hold != null && hold.length() > 1) { - contentTMinusStatus.setText(hold); + @Override + public void onFinish() { + Timber.v("Countdown finished."); + contentTMinusStatus.setTypeface(Typeface.DEFAULT); + if (sharedPreference.isNightModeActive(context)) { + contentTMinusStatus.setTextColor(nightColor); } else { + contentTMinusStatus.setTextColor(color); + } + if (status == 1) { contentTMinusStatus.setText("Watch Live webcast for up to date status."); + + } else { + if (hold != null && hold.length() > 1) { + contentTMinusStatus.setText(hold); + } else { + contentTMinusStatus.setText("Watch Live webcast for up to date status."); + } } + contentTMinusStatus.setVisibility(View.VISIBLE); + countdownDays.setText("- -"); + countdownHours.setText("- -"); + countdownMinutes.setText("- -"); + countdownSeconds.setText("- -"); } - contentTMinusStatus.setVisibility(View.VISIBLE); - countdownDays.setText("- -"); - countdownHours.setText("- -"); - countdownMinutes.setText("- -"); - countdownSeconds.setText("- -"); - } - @Override - public void onTick(long millisUntilFinished) { - time.setLength(0); - - // Calculate the Days/Hours/Mins/Seconds numerically. - long longDays = millisUntilFinished / 86400000; - long longHours = (millisUntilFinished / 3600000) % 24; - long longMins = (millisUntilFinished / 60000) % 60; - long longSeconds = (millisUntilFinished / 1000) % 60; - - String days = String.valueOf(longDays); - String hours; - String minutes; - String seconds; - - // Translate those numerical values to string values. - if (longHours < 10) { - hours = "0" + String.valueOf(longHours); - } else { - hours = String.valueOf(longHours); - } + @Override + public void onTick(long millisUntilFinished) { + time.setLength(0); + + // Calculate the Days/Hours/Mins/Seconds numerically. + long longDays = millisUntilFinished / 86400000; + long longHours = (millisUntilFinished / 3600000) % 24; + long longMins = (millisUntilFinished / 60000) % 60; + long longSeconds = (millisUntilFinished / 1000) % 60; + + String days = String.valueOf(longDays); + String hours; + String minutes; + String seconds; + + // Translate those numerical values to string values. + if (longHours < 10) { + hours = "0" + String.valueOf(longHours); + } else { + hours = String.valueOf(longHours); + } - if (longMins < 10) { - minutes = "0" + String.valueOf(longMins); - } else { - minutes = String.valueOf(longMins); - } + if (longMins < 10) { + minutes = "0" + String.valueOf(longMins); + } else { + minutes = String.valueOf(longMins); + } - if (longSeconds < 10) { - seconds = "0" + String.valueOf(longSeconds); - } else { - seconds = String.valueOf(longSeconds); - } + if (longSeconds < 10) { + seconds = "0" + String.valueOf(longSeconds); + } else { + seconds = String.valueOf(longSeconds); + } - // Update the views - if (Integer.valueOf(days) > 0) { - countdownDays.setText(days); - } else { - countdownDays.setText("- -"); - } + // Update the views + if (Integer.valueOf(days) > 0) { + countdownDays.setText(days); + } else { + countdownDays.setText("- -"); + } - if (Integer.valueOf(hours) > 0) { - countdownHours.setText(hours); - } else if (Integer.valueOf(days) > 0) { - countdownHours.setText("00"); - } else { - countdownHours.setText("- -"); - } + if (Integer.valueOf(hours) > 0) { + countdownHours.setText(hours); + } else if (Integer.valueOf(days) > 0) { + countdownHours.setText("00"); + } else { + countdownHours.setText("- -"); + } - if (Integer.valueOf(minutes) > 0) { - countdownMinutes.setText(minutes); - } else if (Integer.valueOf(hours) > 0 || Integer.valueOf(days) > 0) { - countdownMinutes.setText("00"); - } else { - countdownMinutes.setText("- -"); - } + if (Integer.valueOf(minutes) > 0) { + countdownMinutes.setText(minutes); + } else if (Integer.valueOf(hours) > 0 || Integer.valueOf(days) > 0) { + countdownMinutes.setText("00"); + } else { + countdownMinutes.setText("- -"); + } - if (Integer.valueOf(seconds) > 0) { - countdownSeconds.setText(seconds); - } else if (Integer.valueOf(minutes) > 0 || Integer.valueOf(hours) > 0 || Integer.valueOf(days) > 0) { - countdownSeconds.setText("00"); - } else { - countdownSeconds.setText("- -"); - } + if (Integer.valueOf(seconds) > 0) { + countdownSeconds.setText(seconds); + } else if (Integer.valueOf(minutes) > 0 || Integer.valueOf(hours) > 0 || Integer.valueOf(days) > 0) { + countdownSeconds.setText("00"); + } else { + countdownSeconds.setText("- -"); + } - // Hide status if countdown is active. - contentTMinusStatus.setVisibility(View.GONE); - } - }.start(); + // Hide status if countdown is active. + contentTMinusStatus.setVisibility(View.GONE); + } + }.start(); + } } else { countdownLayout.setVisibility(View.GONE); @@ -1044,7 +1052,6 @@ private void setWindowStamp() { } TimeZone timeZone = dateFormat.getTimeZone(); - launchWindowTitle.setText("Launch Window"); launchWindowText.setText(String.format("%s %s", dateFormat.format(windowStart), timeZone.getDisplayName(false, TimeZone.SHORT))); @@ -1055,7 +1062,6 @@ private void setWindowStamp() { } TimeZone timeZone = dateFormat.getTimeZone(); - launchWindowTitle.setText("Launch Window"); launchWindowText.setText(String.format("%s %s", dateFormat.format(windowStart), timeZone.getDisplayName(false, TimeZone.SHORT))); @@ -1066,7 +1072,6 @@ private void setWindowStamp() { } TimeZone timeZone = dateFormat.getTimeZone(); - launchWindowTitle.setText("Launch Window"); launchWindowText.setText(String.format("%s - %s %s", dateFormat.format(windowStart), dateFormat.format(windowEnd), diff --git a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java index 63438d7e4..015abaea9 100644 --- a/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java +++ b/mobile/src/main/java/me/calebjones/spacelaunchnow/ui/main/MainActivity.java @@ -9,6 +9,7 @@ import android.os.Handler; import android.preference.PreferenceManager; import android.support.annotation.NonNull; +import android.support.design.widget.CoordinatorLayout; import android.support.v4.app.FragmentManager; import android.support.v4.content.ContextCompat; import android.support.v4.view.GravityCompat; @@ -19,6 +20,7 @@ import android.view.MenuItem; import android.view.View; import android.widget.RelativeLayout; +import android.widget.Toast; import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.GravityEnum; @@ -41,10 +43,13 @@ import com.mikepenz.materialdrawer.model.SecondaryDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; + import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; +import java.util.concurrent.TimeUnit; + import butterknife.BindView; import butterknife.ButterKnife; import de.mrapp.android.preference.activity.PreferenceActivity; @@ -80,6 +85,8 @@ public class MainActivity extends BaseActivity { AdView adView; @BindView(R.id.container) RelativeLayout container; + @BindView(R.id.coordinatorLayout) + CoordinatorLayout coordinatorLayout; private LaunchesViewPager mlaunchesViewPager; private MissionFragment mMissionFragment; private NextLaunchFragment mUpcomingFragment; @@ -91,6 +98,7 @@ public class MainActivity extends BaseActivity { private CustomTabActivityHelper customTabActivityHelper; private Context context; private boolean adviewEnabled = false; +// private Rate rate; static final int SHOW_INTRO = 1; @@ -201,6 +209,21 @@ public void onAdLoaded() { .withSavedInstance(savedInstanceState) .build(); +// rate = new Rate.Builder(context) // Optional, defaults to 6 +// .setMinimumInstallTime(0) // Optional, defaults to 7 days +// .setFeedbackAction(new OnFeedbackListener() { // Optional +// @Override +// public void onFeedbackTapped() { +// Toast.makeText(MainActivity.this, "Meh", Toast.LENGTH_SHORT).show(); +// } +// }) +// .setSnackBarParent(coordinatorLayout) // Optional, shows dialog by default +// .setMessage("Hello") // Optional +// .setPositiveButton("Sure!") // Optional +// .setCancelButton("Maybe later") // Optional +// .setNegativeButton("Nope!") // Optional +// .build(); + result = new DrawerBuilder() .withActivity(this) .withTranslucentStatusBar(true) diff --git a/mobile/src/main/res/layout-night/fragment_launches_view_pager.xml b/mobile/src/main/res/layout-night/fragment_launches_view_pager.xml index 3d0c8240b..60bb4f7f8 100644 --- a/mobile/src/main/res/layout-night/fragment_launches_view_pager.xml +++ b/mobile/src/main/res/layout-night/fragment_launches_view_pager.xml @@ -3,8 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" - tools:context=".ui.main.MainActivity"> + android:layout_height="match_parent"> - - - - - - + + + + + + + + - + android:layout_height="match_parent" + android:layout_marginEnd="28dp" + android:layout_marginStart="28dp" /> + android:textSize="18sp" /> - - - - - - - - - + android:layout_marginTop="2dp" + android:orientation="horizontal"> - - + + + diff --git a/mobile/src/main/res/layout/activity_main.xml b/mobile/src/main/res/layout/activity_main.xml index 15d8e7712..bcb95a9dd 100644 --- a/mobile/src/main/res/layout/activity_main.xml +++ b/mobile/src/main/res/layout/activity_main.xml @@ -1,34 +1,40 @@ - + android:fitsSystemWindows="true"> - + android:layout_height="match_parent" + android:fitsSystemWindows="true" + tools:openDrawer="start"> - + android:layout_height="match_parent"> - - - + + + + + + \ No newline at end of file diff --git a/mobile/src/main/res/layout/app_bar_main.xml b/mobile/src/main/res/layout/app_bar_main.xml index 08e7ec682..fb55e66c9 100644 --- a/mobile/src/main/res/layout/app_bar_main.xml +++ b/mobile/src/main/res/layout/app_bar_main.xml @@ -10,8 +10,8 @@ + android:elevation="8dp" + android:theme="@style/AppTheme.AppBarOverlay"> + app:popupTheme="@style/AppTheme.PopupOverlay" /> - - - - - - - - - - -