├── OLD ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── app │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── values │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── menu │ │ │ │ │ ├── main.xml │ │ │ │ │ └── activity_main_drawer.xml │ │ │ │ ├── layout │ │ │ │ │ ├── detail_activity.xml │ │ │ │ │ ├── detail_post_fragment.xml │ │ │ │ │ ├── nav_header_main.xml │ │ │ │ │ ├── home_post_list_fragment.xml │ │ │ │ │ ├── item.xml │ │ │ │ │ └── main_activity.xml │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── layout-sw600dp │ │ │ │ │ └── main_activity.xml │ │ │ │ ├── drawable-v24 │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ └── drawable │ │ │ │ │ └── ic_launcher_background.xml │ │ │ ├── java │ │ │ │ └── fr │ │ │ │ │ └── ec │ │ │ │ │ └── producthunt │ │ │ │ │ ├── data │ │ │ │ │ ├── repository │ │ │ │ │ │ └── post │ │ │ │ │ │ │ ├── Repo.java │ │ │ │ │ │ │ ├── remote │ │ │ │ │ │ │ ├── PostRemoteRepositoryException.java │ │ │ │ │ │ │ └── PostRemoteRepository.java │ │ │ │ │ │ │ └── mapper │ │ │ │ │ │ │ └── PostMapper.java │ │ │ │ │ ├── api │ │ │ │ │ │ ├── model │ │ │ │ │ │ │ ├── PostResponseList.java │ │ │ │ │ │ │ ├── ThumbnailResponse.java │ │ │ │ │ │ │ └── PostResponse.java │ │ │ │ │ │ ├── ProductHuntService.java │ │ │ │ │ │ └── ServiceApiFactory.java │ │ │ │ │ ├── database │ │ │ │ │ │ ├── dao │ │ │ │ │ │ │ └── PostDao.java │ │ │ │ │ │ ├── RoomProductHuntDb.java │ │ │ │ │ │ ├── ProductHuntDbHelper.java │ │ │ │ │ │ ├── OldPostDao.java │ │ │ │ │ │ └── DataBaseContract.java │ │ │ │ │ ├── JsonPostParser.java │ │ │ │ │ ├── model │ │ │ │ │ │ └── Post.java │ │ │ │ │ ├── DataProvider.java │ │ │ │ │ └── SyncService.java │ │ │ │ │ └── ui │ │ │ │ │ ├── detail │ │ │ │ │ ├── DetailActivity.java │ │ │ │ │ └── DetailPostFragment.java │ │ │ │ │ └── home │ │ │ │ │ ├── PostAdapter.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── PostsFragments.java │ │ │ └── AndroidManifest.xml │ │ ├── test │ │ │ └── java │ │ │ │ └── fr │ │ │ │ └── ec │ │ │ │ └── producthunt │ │ │ │ └── ExampleUnitTest.java │ │ └── androidTest │ │ │ └── java │ │ │ └── fr │ │ │ └── ec │ │ │ └── producthunt │ │ │ └── ExampleInstrumentedTest.java │ ├── proguard-rules.pro │ ├── build.gradle │ ├── gradlew.bat │ └── gradlew ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── settings.gradle ├── doc └── Consignes_Project.pdf ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── app ├── src │ ├── main │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── menu │ │ │ │ └── main.xml │ │ │ ├── layout │ │ │ │ ├── detail_activity.xml │ │ │ │ ├── main_activity.xml │ │ │ │ ├── detail_post_fragment.xml │ │ │ │ ├── home_post_list_fragment.xml │ │ │ │ ├── item.xml │ │ │ │ └── main_item.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── layout-sw600dp │ │ │ │ └── main_activity.xml │ │ │ ├── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ └── drawable │ │ │ │ └── ic_launcher_background.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── fr │ │ │ └── ec │ │ │ └── producthunt │ │ │ ├── ui │ │ │ ├── detail │ │ │ │ ├── DetailActivity.java │ │ │ │ └── DetailPostFragment.java │ │ │ └── home │ │ │ │ ├── MainActivity.java │ │ │ │ ├── PostAdapter.java │ │ │ │ └── PostsFragments.java │ │ │ └── data │ │ │ ├── database │ │ │ ├── ProductHuntDbHelper.java │ │ │ ├── PostDao.java │ │ │ └── DataBaseContract.java │ │ │ ├── model │ │ │ └── Post.java │ │ │ ├── JsonPostParser.java │ │ │ ├── SyncService.java │ │ │ └── DataProvider.java │ ├── test │ │ └── java │ │ │ └── fr │ │ │ └── ec │ │ │ └── producthunt │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── fr │ │ └── ec │ │ └── producthunt │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── gradle.properties ├── .gitignore ├── gradlew.bat └── gradlew /OLD/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /doc/Consignes_Project.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/doc/Consignes_Project.pdf -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /OLD/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /OLD/app/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/repository/post/Repo.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.repository.post; 2 | 3 | public class Repo { 4 | } 5 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NansD/ProductHunt/master/OLD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ProductHunt 3 | Actualiser 4 | Veuillez actualiser 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/api/model/PostResponseList.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.api.model; 2 | 3 | import fr.ec.producthunt.data.model.Post; 4 | import java.util.List; 5 | 6 | public class PostResponseList { 7 | public List posts; 8 | } 9 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/api/model/ThumbnailResponse.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.api.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public class ThumbnailResponse { 6 | @SerializedName("image_url") 7 | public String imageUrl; 8 | } 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Feb 11 17:28:25 CET 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /OLD/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat May 18 11:51:38 CEST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /OLD/app/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat May 18 13:40:01 CEST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/detail_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/layout/detail_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/repository/post/remote/PostRemoteRepositoryException.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.repository.post.remote; 2 | 3 | public class PostRemoteRepositoryException extends Exception { 4 | 5 | public PostRemoteRepositoryException(Throwable cause) { 6 | super(cause); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ProductHunt 3 | Actualiser 4 | Veuillez actualiser 5 | close 6 | open 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/fr/ec/producthunt/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test public void addition_isCorrect() throws Exception { 14 | assertEquals(4, 2 + 2); 15 | } 16 | } -------------------------------------------------------------------------------- /OLD/app/src/test/java/fr/ec/producthunt/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test public void addition_isCorrect() throws Exception { 14 | assertEquals(4, 2 + 2); 15 | } 16 | } -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/api/model/PostResponse.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.api.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public class PostResponse { 6 | @SerializedName("") public long id; 7 | 8 | @SerializedName("name") public String title; 9 | 10 | @SerializedName("tagline") public String subTitle; 11 | 12 | @SerializedName("redirect_url") public String postUrl; 13 | 14 | @SerializedName("thumbnail") public ThumbnailResponse thumbnail; 15 | } 16 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/database/dao/PostDao.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.database.dao; 2 | 3 | import androidx.room.Dao; 4 | import androidx.room.Insert; 5 | import androidx.room.OnConflictStrategy; 6 | import androidx.room.Query; 7 | import fr.ec.producthunt.data.model.Post; 8 | import java.util.List; 9 | 10 | @Dao 11 | public interface PostDao { 12 | @Query("SELECT * FROM posts") 13 | List getPosts(); 14 | 15 | @Insert(onConflict = OnConflictStrategy.REPLACE) 16 | void save(List posts); 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/api/ProductHuntService.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.api; 2 | 3 | import fr.ec.producthunt.data.api.model.PostResponse; 4 | import fr.ec.producthunt.data.api.model.PostResponseList; 5 | import fr.ec.producthunt.data.model.Post; 6 | import java.util.List; 7 | import retrofit2.Call; 8 | import retrofit2.http.GET; 9 | 10 | public interface ProductHuntService { 11 | @GET("posts?access_token=46a03e1c32ea881c8afb39e59aa17c936ff4205a8ed418f525294b2b45b56abb") 12 | Call getPosts(); 13 | } 14 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/api/ServiceApiFactory.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.api; 2 | 3 | import retrofit2.Retrofit; 4 | import retrofit2.converter.gson.GsonConverterFactory; 5 | 6 | public class ServiceApiFactory { 7 | 8 | private static final String BASE_URL = "https://api.producthunt.com/v1/"; 9 | private static Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL) 10 | .addConverterFactory(GsonConverterFactory.create()) 11 | .build(); 12 | 13 | 14 | public static T create(Class service) { 15 | return retrofit.create(service); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /OLD/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.4.1' 11 | 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/main_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/layout-sw600dp/main_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /OLD/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/menu/activity_main_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 11 | 12 | 15 | 18 | 19 | 20 | 23 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /OLD/app/src/androidTest/java/fr/ec/producthunt/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { 18 | @Test public void useAppContext() throws Exception { 19 | // Context of the app under test. 20 | Context appContext = InstrumentationRegistry.getTargetContext(); 21 | 22 | assertEquals("fr.ec.producthunt", appContext.getPackageName()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/layout/detail_post_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/detail_post_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /OLD/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | android.enableJetifier=true 13 | android.useAndroidX=true 14 | org.gradle.jvmargs=-Xmx1536m 15 | 16 | # When configured, Gradle will run in incubating parallel mode. 17 | # This option should only be used with decoupled projects. More details, visit 18 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 19 | # org.gradle.parallel=true 20 | -------------------------------------------------------------------------------- /app/src/androidTest/java/fr/ec/producthunt/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { 18 | @Test public void useAppContext() throws Exception { 19 | // Context of the app under test. 20 | Context appContext = InstrumentationRegistry.getTargetContext(); 21 | 22 | assertEquals("fr.ec.producthunt", appContext.getPackageName()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/repository/post/mapper/PostMapper.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.repository.post.mapper; 2 | 3 | import fr.ec.producthunt.data.api.model.PostResponse; 4 | import fr.ec.producthunt.data.model.Post; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class PostMapper { 9 | 10 | public List from(List postResponses) { 11 | List posts = new ArrayList<>(postResponses.size()); 12 | for (PostResponse postResponse : postResponses) { 13 | posts.add(from(postResponse)); 14 | } 15 | 16 | return posts; 17 | } 18 | 19 | private Post from(PostResponse postResponse) { 20 | Post post = new Post(); 21 | post.setId(postResponse.id); 22 | post.setImageUrl(postResponse.thumbnail.imageUrl); 23 | post.setSubTitle(postResponse.subTitle); 24 | post.setPostUrl(postResponse.postUrl); 25 | return post; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/database/RoomProductHuntDb.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.database; 2 | 3 | import android.content.Context; 4 | import androidx.room.Database; 5 | import androidx.room.Room; 6 | import androidx.room.RoomDatabase; 7 | import fr.ec.producthunt.data.database.dao.PostDao; 8 | import fr.ec.producthunt.data.model.Post; 9 | 10 | @Database(entities = { Post.class, }, version = 3) 11 | public abstract class RoomProductHuntDb extends RoomDatabase { 12 | 13 | public abstract PostDao postDeo(); 14 | 15 | //SINGLETON 16 | private static RoomProductHuntDb INSTANCE; 17 | 18 | public static RoomProductHuntDb getDatabase(final Context context) { 19 | if (INSTANCE == null) { 20 | synchronized (RoomProductHuntDb.class) { 21 | if (INSTANCE == null) { 22 | INSTANCE = Room.databaseBuilder(context.getApplicationContext(), RoomProductHuntDb.class, 23 | "roomproducthuntdb").build(); 24 | } 25 | } 26 | } 27 | return INSTANCE; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | defaultConfig { 6 | applicationId "fr.ec.producthunt" 7 | minSdkVersion 21 8 | targetSdkVersion 26 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(include: ['*.jar'], dir: 'libs') 23 | implementation 'com.android.support:appcompat-v7:26.1.0' 24 | 25 | implementation 'com.squareup.picasso:picasso:2.5.2' 26 | 27 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 28 | testImplementation 'junit:junit:4.12' 29 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 30 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 31 | } 32 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/layout/nav_header_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 20 | 21 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /OLD/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/ui/detail/DetailActivity.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.detail; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v4.app.FragmentManager; 6 | import android.support.v7.app.AppCompatActivity; 7 | import fr.ec.producthunt.R; 8 | 9 | public class DetailActivity extends AppCompatActivity { 10 | 11 | public static final String POST_URL_KEY = "post_url_key"; 12 | 13 | @Override protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.detail_activity); 16 | 17 | FragmentManager fragmentManager = getSupportFragmentManager(); 18 | 19 | fragmentManager.beginTransaction() 20 | .add(R.id.detail_container, DetailPostFragment.getNewInstance(obtainPostUrlFromIntent())) 21 | .commit(); 22 | } 23 | 24 | private String obtainPostUrlFromIntent() { 25 | 26 | Intent intent = getIntent(); 27 | if (intent.getExtras().containsKey(POST_URL_KEY)) { 28 | return intent.getExtras().getString(POST_URL_KEY); 29 | } else { 30 | throw new IllegalStateException("Il faut passer l'url du post"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/ui/detail/DetailActivity.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.detail; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import androidx.fragment.app.FragmentManager; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | import fr.ec.producthunt.R; 8 | 9 | public class DetailActivity extends AppCompatActivity { 10 | 11 | public static final String POST_URL_KEY = "post_url_key"; 12 | 13 | @Override protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.detail_activity); 16 | 17 | FragmentManager fragmentManager = getSupportFragmentManager(); 18 | 19 | fragmentManager.beginTransaction() 20 | .add(R.id.detail_container, DetailPostFragment.getNewInstance(obtainPostUrlFromIntent())) 21 | .commit(); 22 | } 23 | 24 | private String obtainPostUrlFromIntent() { 25 | 26 | Intent intent = getIntent(); 27 | if (intent.getExtras().containsKey(POST_URL_KEY)) { 28 | return intent.getExtras().getString(POST_URL_KEY); 29 | } else { 30 | throw new IllegalStateException("Il faut passer l'url du post"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/repository/post/remote/PostRemoteRepository.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.repository.post.remote; 2 | 3 | import android.util.Log; 4 | import fr.ec.producthunt.data.api.ProductHuntService; 5 | import fr.ec.producthunt.data.api.ServiceApiFactory; 6 | import fr.ec.producthunt.data.api.model.PostResponse; 7 | import fr.ec.producthunt.data.model.Post; 8 | import fr.ec.producthunt.data.repository.post.mapper.PostMapper; 9 | import java.util.List; 10 | 11 | import static android.content.ContentValues.TAG; 12 | 13 | public class PostRemoteRepository { 14 | 15 | private final ProductHuntService service; 16 | private final PostMapper postMapper; 17 | 18 | public PostRemoteRepository() { 19 | service = ServiceApiFactory.create(ProductHuntService.class); 20 | postMapper = new PostMapper(); 21 | 22 | } 23 | 24 | public List getPosts() throws PostRemoteRepositoryException { 25 | try { 26 | List postResponseList = service.getPosts().execute().body().posts; 27 | return postMapper.from(postResponseList); 28 | 29 | } catch (Exception e) { 30 | Log.e(TAG, "syncPost: Fails", e); 31 | throw new PostRemoteRepositoryException(e.getCause()); 32 | 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/data/database/ProductHuntDbHelper.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.database; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.database.sqlite.SQLiteDatabase; 6 | import android.database.sqlite.SQLiteOpenHelper; 7 | 8 | /** 9 | * @author Mohammed Boukadir @:mohammed.boukadir@gmail.com 10 | */ 11 | public class ProductHuntDbHelper extends SQLiteOpenHelper { 12 | 13 | private static ProductHuntDbHelper productHuntDbHelper; 14 | 15 | public static ProductHuntDbHelper getInstance(Application application) { 16 | 17 | if(productHuntDbHelper == null){ 18 | productHuntDbHelper = new ProductHuntDbHelper(application); 19 | } 20 | 21 | return productHuntDbHelper; 22 | } 23 | 24 | private ProductHuntDbHelper(Context context) { 25 | super(context, DataBaseContract.DATABASE_NAME, null, DataBaseContract.DATABASE_VERSION); 26 | } 27 | 28 | @Override public void onCreate(SQLiteDatabase db) { 29 | db.execSQL(DataBaseContract.PostTable.SQL_CREATE_POST_TABLE); 30 | } 31 | 32 | @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 33 | onUpgrade(db, oldVersion, newVersion); 34 | db.execSQL(DataBaseContract.PostTable.SQL_DROP_POST_TABLE); 35 | onCreate(db); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/database/ProductHuntDbHelper.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.database; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.database.sqlite.SQLiteDatabase; 6 | import android.database.sqlite.SQLiteOpenHelper; 7 | 8 | /** 9 | * @author Mohammed Boukadir @:mohammed.boukadir@gmail.com 10 | */ 11 | public class ProductHuntDbHelper extends SQLiteOpenHelper { 12 | 13 | private static ProductHuntDbHelper productHuntDbHelper; 14 | 15 | public static ProductHuntDbHelper getInstance(Application application) { 16 | 17 | if(productHuntDbHelper == null){ 18 | productHuntDbHelper = new ProductHuntDbHelper(application); 19 | } 20 | 21 | return productHuntDbHelper; 22 | } 23 | 24 | private ProductHuntDbHelper(Context context) { 25 | super(context, DataBaseContract.DATABASE_NAME, null, DataBaseContract.DATABASE_VERSION); 26 | } 27 | 28 | @Override public void onCreate(SQLiteDatabase db) { 29 | db.execSQL(DataBaseContract.PostTable.SQL_CREATE_POST_TABLE); 30 | } 31 | 32 | @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 33 | onUpgrade(db, oldVersion, newVersion); 34 | db.execSQL(DataBaseContract.PostTable.SQL_DROP_POST_TABLE); 35 | onCreate(db); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /OLD/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "fr.ec.producthunt" 7 | minSdkVersion 21 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(include: ['*.jar'], dir: 'libs') 23 | implementation 'androidx.appcompat:appcompat:1.1.0-alpha03' 24 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 25 | implementation "androidx.room:room-runtime:2.1.0-alpha04" 26 | annotationProcessor "androidx.room:room-compiler:2.1.0-alpha04" 27 | 28 | //RETROFIT 29 | implementation "com.squareup.retrofit2:retrofit:2.5.0" 30 | implementation "com.squareup.retrofit2:converter-gson:2.3.0" 31 | 32 | implementation 'com.squareup.picasso:picasso:2.5.2' 33 | 34 | testImplementation 'junit:junit:4.12' 35 | androidTestImplementation 'androidx.test:runner:1.1.2-alpha02' 36 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha02' 37 | implementation 'org.jetbrains:annotations-java5:15.0' 38 | implementation 'com.android.support:design:28.0.0-alpha3' 39 | 40 | } 41 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/layout/home_post_list_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 21 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/res/layout/home_post_list_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 21 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/layout/item.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 17 | 24 | 25 | 34 | 35 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/database/OldPostDao.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.database; 2 | 3 | import android.database.Cursor; 4 | import fr.ec.producthunt.data.model.Post; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * @author Mohammed Boukadir @:mohammed.boukadir@gmail.com 10 | */ 11 | public class OldPostDao { 12 | 13 | private final ProductHuntDbHelper productHuntDbHelper; 14 | 15 | public OldPostDao(ProductHuntDbHelper productHuntDbHelper) { 16 | this.productHuntDbHelper = productHuntDbHelper; 17 | } 18 | 19 | public long save(Post post) { 20 | return productHuntDbHelper.getWritableDatabase() 21 | .replace(DataBaseContract.PostTable.TABLE_NAME, null, post.toContentValues()); 22 | } 23 | 24 | public List retrievePosts() { 25 | 26 | 27 | Cursor cursor = productHuntDbHelper.getReadableDatabase() 28 | .query(DataBaseContract.PostTable.TABLE_NAME, 29 | DataBaseContract.PostTable.PROJECTIONS, 30 | null, null, null, null, null); 31 | 32 | List posts = new ArrayList<>(cursor.getCount()); 33 | 34 | if (cursor.moveToFirst()) { 35 | do { 36 | 37 | Post post = new Post(); 38 | 39 | post.setId(cursor.getInt(0)); 40 | post.setTitle(cursor.getString(1)); 41 | post.setSubTitle(cursor.getString(2)); 42 | post.setImageUrl(cursor.getString(3)); 43 | post.setPostUrl(cursor.getString(4)); 44 | 45 | posts.add(post); 46 | 47 | 48 | } while (cursor.moveToNext()); 49 | } 50 | 51 | cursor.close(); 52 | 53 | return posts; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/ui/home/MainActivity.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.home; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.widget.FrameLayout; 8 | import fr.ec.producthunt.R; 9 | import fr.ec.producthunt.data.model.Post; 10 | import fr.ec.producthunt.ui.detail.DetailActivity; 11 | import fr.ec.producthunt.ui.detail.DetailPostFragment; 12 | 13 | public class MainActivity extends AppCompatActivity implements PostsFragments.Callback { 14 | 15 | private boolean towPane; 16 | 17 | @Override protected void onCreate(@Nullable Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.main_activity); 20 | 21 | FrameLayout detailContainer = findViewById(R.id.home_detail_container); 22 | 23 | if (detailContainer != null) { 24 | towPane = true; 25 | getSupportFragmentManager().beginTransaction() 26 | .add(R.id.home_detail_container, DetailPostFragment.getNewInstance(null)) 27 | .commit(); 28 | } 29 | } 30 | 31 | @Override public void onClickPost(Post post) { 32 | 33 | if (towPane) { 34 | DetailPostFragment detailPostFragment = 35 | (DetailPostFragment) getSupportFragmentManager().findFragmentById(R.id.home_detail_container); 36 | 37 | if (detailPostFragment != null) { 38 | detailPostFragment.loadUrl(post.getPostUrl()); 39 | } 40 | } else { 41 | 42 | Intent intent = new Intent(this, DetailActivity.class); 43 | intent.putExtra(DetailActivity.POST_URL_KEY, post.getPostUrl()); 44 | 45 | startActivity(intent); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS-specific files 2 | .DS_Store 3 | .DS_Store? 4 | ._* 5 | .Spotlight-V100 6 | .Trashes 7 | ehthumbs.db 8 | Thumbs.db 9 | 10 | # Built application files 11 | *.apk 12 | *.ap_ 13 | *.aab 14 | 15 | # Files for the ART/Dalvik VM 16 | *.dex 17 | 18 | # Java class files 19 | *.class 20 | 21 | # Generated files 22 | bin/ 23 | gen/ 24 | out/ 25 | 26 | # Gradle files 27 | .gradle/ 28 | build/ 29 | /*/build/ 30 | 31 | # Local configuration file (sdk path, etc) 32 | local.properties 33 | 34 | # Proguard folder generated by Eclipse 35 | proguard/ 36 | 37 | # Log Files 38 | *.log 39 | 40 | # Android Studio Navigation editor temp files 41 | .navigation/ 42 | 43 | # Android Studio captures folder 44 | captures/ 45 | 46 | # IntelliJ 47 | *.iml 48 | .idea/workspace.xml 49 | .idea/tasks.xml 50 | .idea/gradle.xml 51 | .idea/assetWizardSettings.xml 52 | .idea/dictionaries 53 | .idea/libraries 54 | .idea/caches 55 | .idea/ 56 | # Android Studio 3 in .gitignore file. 57 | .idea/caches/build_file_checksums.ser 58 | .idea/modules.xml 59 | 60 | # Keystore files 61 | # Uncomment the following lines if you do not want to check your keystore files in. 62 | #*.jks 63 | #*.keystore 64 | 65 | # External native build folder generated in Android Studio 2.2 and later 66 | .externalNativeBuild 67 | 68 | # Google Services (e.g. APIs or Firebase) 69 | # google-services.json 70 | 71 | # Freeline 72 | freeline.py 73 | freeline/ 74 | freeline_project_description.json 75 | 76 | # fastlane 77 | fastlane/report.xml 78 | fastlane/Preview.html 79 | fastlane/screenshots 80 | fastlane/test_output 81 | fastlane/readme.md 82 | 83 | # Version control 84 | vcs.xml 85 | 86 | # lint 87 | lint/intermediates/ 88 | lint/generated/ 89 | lint/outputs/ 90 | lint/tmp/ 91 | # lint/reports/ 92 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/data/database/PostDao.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.database; 2 | 3 | import android.database.Cursor; 4 | import android.util.Log; 5 | 6 | import fr.ec.producthunt.data.model.Post; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import static android.content.ContentValues.TAG; 11 | 12 | /** 13 | * @author Mohammed Boukadir @:mohammed.boukadir@gmail.com 14 | */ 15 | public class PostDao { 16 | 17 | private final ProductHuntDbHelper productHuntDbHelper; 18 | 19 | public PostDao(ProductHuntDbHelper productHuntDbHelper) { 20 | this.productHuntDbHelper = productHuntDbHelper; 21 | } 22 | 23 | public long save(Post post) { 24 | return productHuntDbHelper.getWritableDatabase() 25 | .replace(DataBaseContract.PostTable.TABLE_NAME, null, post.toContentValues()); 26 | } 27 | 28 | public List retrievePosts() { 29 | 30 | 31 | Cursor cursor = productHuntDbHelper.getReadableDatabase() 32 | .query(DataBaseContract.PostTable.TABLE_NAME, 33 | DataBaseContract.PostTable.PROJECTIONS, 34 | null, null, null, null, null); 35 | 36 | List posts = new ArrayList<>(cursor.getCount()); 37 | 38 | if (cursor.moveToFirst()) { 39 | do { 40 | 41 | Post post = new Post(); 42 | 43 | post.setId(cursor.getInt(0)); 44 | post.setTitle(cursor.getString(1)); 45 | post.setSubTitle(cursor.getString(2)); 46 | post.setImageUrl(cursor.getString(3)); 47 | post.setPostUrl(cursor.getString(4)); 48 | post.setCommentNumber(cursor.getString(5)); 49 | 50 | posts.add(post); 51 | 52 | 53 | } while (cursor.moveToNext()); 54 | } 55 | 56 | cursor.close(); 57 | 58 | return posts; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/JsonPostParser.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data; 2 | 3 | import fr.ec.producthunt.data.model.Post; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import org.json.JSONArray; 8 | import org.json.JSONException; 9 | import org.json.JSONObject; 10 | 11 | /** 12 | * @author Mohammed Boukadir @:mohammed.boukadir@gmail.com 13 | */ 14 | public class JsonPostParser { 15 | 16 | public List jsonToPosts(String json) { 17 | 18 | try { 19 | 20 | JSONObject postsRespnse = new JSONObject(json); 21 | JSONArray postsJson = postsRespnse.getJSONArray("posts"); 22 | 23 | int size = postsJson.length(); 24 | 25 | ArrayList posts = new ArrayList(size); 26 | 27 | for (int i = 0; i < postsJson.length(); i++) { 28 | JSONObject postJson = (JSONObject) postsJson.get(i); 29 | 30 | posts.add(jsonToPost(postJson)); 31 | } 32 | 33 | return posts; 34 | } catch (JSONException e) { 35 | e.printStackTrace(); 36 | return Collections.emptyList(); 37 | } 38 | } 39 | 40 | private Post jsonToPost(JSONObject postJson) throws JSONException { 41 | Post post = new Post(); 42 | //"thumbnail": { 43 | // "id": 139278, 44 | // "media_type": "image", 45 | // "image_url": "https://ph-files.imgix.net/b27175ba-ff99-4099-9092-1e8e8fb1cc77?auto=format&w=430&h=570&fit=max", 46 | // "metadata": {} 47 | //}, 48 | post.setId(postJson.getInt("id")); 49 | post.setTitle(postJson.getString("name")); 50 | post.setSubTitle(postJson.getString("tagline")); 51 | post.setPostUrl(postJson.getString("redirect_url")); 52 | 53 | post.setImageUrl(postJson.getJSONObject("thumbnail").getString("image_url")); 54 | 55 | 56 | return post; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/model/Post.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.model; 2 | 3 | import android.content.ContentValues; 4 | import androidx.room.Entity; 5 | import androidx.room.PrimaryKey; 6 | import fr.ec.producthunt.data.database.DataBaseContract; 7 | 8 | @Entity(tableName = "posts") 9 | public class Post { 10 | 11 | @PrimaryKey 12 | private long id; 13 | private String title; 14 | private String subTitle; 15 | private String imageUrl; 16 | private String postUrl; 17 | 18 | public String getTitle() { 19 | return title; 20 | } 21 | 22 | public void setTitle(String title) { 23 | this.title = title; 24 | } 25 | 26 | public String getSubTitle() { 27 | return subTitle; 28 | } 29 | 30 | public void setSubTitle(String subTitle) { 31 | this.subTitle = subTitle; 32 | } 33 | 34 | public void setImageUrl(String imageUrl) { 35 | this.imageUrl = imageUrl; 36 | } 37 | 38 | public String getImageUrl() { 39 | return imageUrl; 40 | } 41 | 42 | public String getPostUrl() { 43 | return postUrl; 44 | } 45 | 46 | public void setPostUrl(String postUrl) { 47 | this.postUrl = postUrl; 48 | } 49 | 50 | public void setId(long id) { 51 | this.id = id; 52 | } 53 | 54 | public long getId() { 55 | return id; 56 | } 57 | 58 | public ContentValues toContentValues() { 59 | 60 | ContentValues contentValues = new ContentValues(); 61 | contentValues.put(DataBaseContract.PostTable.ID_COLUMN, id); 62 | contentValues.put(DataBaseContract.PostTable.TITLE_COLUMN, title); 63 | contentValues.put(DataBaseContract.PostTable.SUBTITLE_COLUMN, subTitle); 64 | contentValues.put(DataBaseContract.PostTable.IMAGE_URL_COLUMN, imageUrl); 65 | contentValues.put(DataBaseContract.PostTable.POST_URL_COLUMN, postUrl); 66 | return contentValues; 67 | } 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/database/DataBaseContract.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.database; 2 | 3 | import android.provider.BaseColumns; 4 | 5 | /** 6 | * @author Mohammed Boukadir @:mohammed.boukadir@gmail.com 7 | */ 8 | public final class DataBaseContract { 9 | 10 | public static final String DATABASE_NAME = "database"; 11 | public static final int DATABASE_VERSION = 1; 12 | 13 | public static final String TEXT_TYPE = " TEXT"; 14 | public static final String COMM_SPA = ","; 15 | public static final String INTEGER_TYPE = " INTEGER"; 16 | 17 | /** Description de la table des Posts **/ 18 | public static final class PostTable implements BaseColumns { 19 | 20 | public static final String TABLE_NAME = "post"; 21 | 22 | public static final String ID_COLUMN = "id"; 23 | public static final String TITLE_COLUMN = "title"; 24 | public static final String SUBTITLE_COLUMN ="subtitle"; 25 | public static final String IMAGE_URL_COLUMN ="imageurl"; 26 | public static final String POST_URL_COLUMN ="postUrl"; 27 | 28 | 29 | 30 | public static final String SQL_CREATE_POST_TABLE = 31 | "CREATE TABLE " +PostTable.TABLE_NAME+" ("+ 32 | PostTable.ID_COLUMN + INTEGER_TYPE+" PRIMARY KEY"+COMM_SPA+ 33 | PostTable.TITLE_COLUMN + TEXT_TYPE +COMM_SPA+ 34 | PostTable.SUBTITLE_COLUMN + TEXT_TYPE +COMM_SPA+ 35 | PostTable.IMAGE_URL_COLUMN + TEXT_TYPE+COMM_SPA+ 36 | PostTable.POST_URL_COLUMN + TEXT_TYPE+ 37 | ")"; 38 | 39 | public static final String SQL_DROP_POST_TABLE = "DROP TABLE IF EXISTS "+TABLE_NAME; 40 | 41 | public static String[] PROJECTIONS = new String[] { 42 | ID_COLUMN, 43 | TITLE_COLUMN, 44 | SUBTITLE_COLUMN, 45 | IMAGE_URL_COLUMN, 46 | POST_URL_COLUMN, 47 | }; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/DataProvider.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.util.Log; 6 | import fr.ec.producthunt.data.database.RoomProductHuntDb; 7 | import fr.ec.producthunt.data.database.dao.PostDao; 8 | import fr.ec.producthunt.data.model.Post; 9 | import fr.ec.producthunt.data.repository.post.remote.PostRemoteRepository; 10 | import fr.ec.producthunt.data.repository.post.remote.PostRemoteRepositoryException; 11 | import java.util.List; 12 | 13 | import static android.content.ContentValues.TAG; 14 | 15 | public class DataProvider { 16 | 17 | public static final String POST_API_END_POINT = 18 | "https://api.producthunt.com/v1/posts?access_token=46a03e1c32ea881c8afb39e59aa17c936ff4205a8ed418f525294b2b45b56abb"; 19 | 20 | private JsonPostParser jsonPostParser = new JsonPostParser(); 21 | 22 | private final PostDao postDao; 23 | private final PostRemoteRepository postRemoteRepository; 24 | 25 | private static DataProvider dataProvider; 26 | 27 | public static DataProvider getInstance(Application application) { 28 | 29 | if (dataProvider == null) { 30 | dataProvider = new DataProvider(application); 31 | } 32 | return dataProvider; 33 | } 34 | 35 | public DataProvider(Context context) { 36 | postDao = RoomProductHuntDb.getDatabase(context).postDeo(); 37 | postRemoteRepository = new PostRemoteRepository(); 38 | } 39 | 40 | public List getPostsFromDatabase() { 41 | return postDao.getPosts(); 42 | } 43 | 44 | public Boolean syncPost() { 45 | 46 | int nb = 0; 47 | 48 | try { 49 | List postList = postRemoteRepository.getPosts(); 50 | postDao.save(postList); 51 | nb = postList.size(); 52 | } catch (PostRemoteRepositoryException e) { 53 | Log.e(TAG, "syncPost: Fails", e); 54 | } 55 | 56 | return nb > 0; 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 17 | 24 | 25 | 34 | 35 | 44 | 45 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/data/model/Post.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.model; 2 | 3 | import android.content.ContentValues; 4 | import fr.ec.producthunt.data.database.DataBaseContract; 5 | 6 | public class Post { 7 | private String title; 8 | private String subTitle; 9 | private String imageUrl; 10 | private String postUrl; 11 | private String commentNumber; 12 | private long id; 13 | 14 | public String getTitle() { 15 | return title; 16 | } 17 | 18 | public void setTitle(String title) { 19 | this.title = title; 20 | } 21 | 22 | public String getSubTitle() { 23 | return subTitle; 24 | } 25 | 26 | public void setSubTitle(String subTitle) { 27 | this.subTitle = subTitle; 28 | } 29 | 30 | public void setImageUrl(String imageUrl) { 31 | this.imageUrl = imageUrl; 32 | } 33 | 34 | public String getImageUrl() { 35 | return imageUrl; 36 | } 37 | 38 | public String getPostUrl() { 39 | return postUrl; 40 | } 41 | 42 | public void setPostUrl(String postUrl) { 43 | this.postUrl = postUrl; 44 | } 45 | 46 | public void setId(long id) { 47 | this.id = id; 48 | } 49 | 50 | public long getId() { 51 | return id; 52 | } 53 | 54 | public String getCommentNumber() {return commentNumber;} 55 | 56 | public void setCommentNumber(String commentNumber) { this.commentNumber = commentNumber;} 57 | 58 | public ContentValues toContentValues() { 59 | 60 | ContentValues contentValues = new ContentValues(); 61 | contentValues.put(DataBaseContract.PostTable.ID_COLUMN, id); 62 | contentValues.put(DataBaseContract.PostTable.TITLE_COLUMN, title); 63 | contentValues.put(DataBaseContract.PostTable.SUBTITLE_COLUMN, subTitle); 64 | contentValues.put(DataBaseContract.PostTable.IMAGE_URL_COLUMN, imageUrl); 65 | contentValues.put(DataBaseContract.PostTable.POST_URL_COLUMN, postUrl); 66 | contentValues.put(DataBaseContract.PostTable.COMMENTS_NUMBER_COLUMN, commentNumber); 67 | return contentValues; 68 | } 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/layout/main_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/data/database/DataBaseContract.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data.database; 2 | 3 | import android.provider.BaseColumns; 4 | 5 | /** 6 | * @author Mohammed Boukadir @:mohammed.boukadir@gmail.com 7 | */ 8 | public final class DataBaseContract { 9 | 10 | public static final String DATABASE_NAME = "database"; 11 | public static final int DATABASE_VERSION = 1; 12 | 13 | public static final String TEXT_TYPE = " TEXT"; 14 | public static final String COMM_SPA = ","; 15 | public static final String INTEGER_TYPE = " INTEGER"; 16 | 17 | /** Description de la table des Posts **/ 18 | public static final class PostTable implements BaseColumns { 19 | 20 | public static final String TABLE_NAME = "post"; 21 | 22 | public static final String ID_COLUMN = "id"; 23 | public static final String TITLE_COLUMN = "title"; 24 | public static final String SUBTITLE_COLUMN ="subtitle"; 25 | public static final String IMAGE_URL_COLUMN ="imageurl"; 26 | public static final String POST_URL_COLUMN ="postUrl"; 27 | public static final String COMMENTS_NUMBER_COLUMN ="commentsNumber"; 28 | 29 | 30 | 31 | public static final String SQL_CREATE_POST_TABLE = 32 | "CREATE TABLE " +PostTable.TABLE_NAME+" ("+ 33 | PostTable.ID_COLUMN + INTEGER_TYPE+" PRIMARY KEY"+COMM_SPA+ 34 | PostTable.TITLE_COLUMN + TEXT_TYPE +COMM_SPA+ 35 | PostTable.SUBTITLE_COLUMN + TEXT_TYPE +COMM_SPA+ 36 | PostTable.IMAGE_URL_COLUMN + TEXT_TYPE+COMM_SPA+ 37 | PostTable.POST_URL_COLUMN + TEXT_TYPE+COMM_SPA+ 38 | PostTable.COMMENTS_NUMBER_COLUMN + TEXT_TYPE+ 39 | ")"; 40 | 41 | public static final String SQL_DROP_POST_TABLE = "DROP TABLE IF EXISTS "+TABLE_NAME; 42 | 43 | public static String[] PROJECTIONS = new String[] { 44 | ID_COLUMN, 45 | TITLE_COLUMN, 46 | SUBTITLE_COLUMN, 47 | IMAGE_URL_COLUMN, 48 | POST_URL_COLUMN, 49 | COMMENTS_NUMBER_COLUMN, 50 | }; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/data/JsonPostParser.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data; 2 | 3 | import android.util.Log; 4 | 5 | import fr.ec.producthunt.data.model.Post; 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | import org.json.JSONArray; 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | import static android.content.ContentValues.TAG; 14 | 15 | /** 16 | * @author Mohammed Boukadir @:mohammed.boukadir@gmail.com 17 | */ 18 | public class JsonPostParser { 19 | 20 | public List jsonToPosts(String json) { 21 | 22 | try { 23 | 24 | JSONObject postsRespnse = new JSONObject(json); 25 | JSONArray postsJson = postsRespnse.getJSONArray("posts"); 26 | 27 | int size = postsJson.length(); 28 | 29 | ArrayList posts = new ArrayList(size); 30 | 31 | for (int i = 0; i < postsJson.length(); i++) { 32 | JSONObject postJson = (JSONObject) postsJson.get(i); 33 | 34 | posts.add(jsonToPost(postJson)); 35 | } 36 | 37 | return posts; 38 | } catch (JSONException e) { 39 | e.printStackTrace(); 40 | return Collections.emptyList(); 41 | } 42 | } 43 | 44 | private Post jsonToPost(JSONObject postJson) throws JSONException { 45 | Post post = new Post(); 46 | //"thumbnail": { 47 | // "id": 139278, 48 | // "media_type": "image", 49 | // "image_url": "https://ph-files.imgix.net/b27175ba-ff99-4099-9092-1e8e8fb1cc77?auto=format&w=430&h=570&fit=max", 50 | // "metadata": {} 51 | //}, 52 | Log.d(TAG, "jsonToPost: " + postJson); 53 | post.setId(postJson.getInt("id")); 54 | post.setTitle(postJson.getString("name")); 55 | post.setSubTitle(postJson.getString("tagline")); 56 | post.setPostUrl(postJson.getString("redirect_url")); 57 | post.setCommentNumber(postJson.getString("comments_count")); 58 | 59 | post.setImageUrl(postJson.getJSONObject("thumbnail").getString("image_url")); 60 | 61 | 62 | return post; 63 | } 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/data/SyncService.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data; 2 | 3 | import android.app.IntentService; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.support.v4.content.LocalBroadcastManager; 7 | import android.util.Log; 8 | 9 | import static android.content.ContentValues.TAG; 10 | import static fr.ec.producthunt.ui.home.PostsFragments.SyncPostReceiver.ACTION_LOAD_POSTS; 11 | 12 | /** 13 | * An {@link IntentService} subclass for handling asynchronous task requests in 14 | * a service on a separate handler thread. 15 | */ 16 | public class SyncService extends IntentService { 17 | private static final String ACTION_FETCH_NEW_POSTS = 18 | "fr.ec.producthunt.data.action.FETCH_NEW_POSTS"; 19 | 20 | public SyncService() { 21 | super("SyncService"); 22 | } 23 | 24 | @Override public void onCreate() { 25 | super.onCreate(); 26 | } 27 | 28 | /** 29 | * Starts this service to perform action Foo with the given parameters. If 30 | * the service is already performing a task this action will be queued. 31 | * 32 | * @see IntentService 33 | */ 34 | public static void startSyncPosts(Context context) { 35 | Intent intent = new Intent(context, SyncService.class); 36 | intent.setAction(ACTION_FETCH_NEW_POSTS); 37 | context.startService(intent); 38 | } 39 | 40 | @Override protected void onHandleIntent(Intent intent) { 41 | if (intent != null) { 42 | final String action = intent.getAction(); 43 | if (ACTION_FETCH_NEW_POSTS.equals(action)) { 44 | handleActionFetchNewPosts(); 45 | Log.d(TAG, "handleActionFetchNewPosts is Ok"); 46 | } 47 | } 48 | } 49 | 50 | /** 51 | * Handle action Foo in the provided background thread with the provided 52 | * parameters. 53 | */ 54 | private void handleActionFetchNewPosts() { 55 | 56 | DataProvider.getInstance(this.getApplication()).syncPost(); 57 | Intent intentToSend = new Intent(); 58 | intentToSend.setAction(ACTION_LOAD_POSTS); 59 | LocalBroadcastManager.getInstance(this).sendBroadcast(intentToSend); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/data/SyncService.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data; 2 | 3 | import android.app.IntentService; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import androidx.localbroadcastmanager.content.LocalBroadcastManager; 7 | import android.util.Log; 8 | 9 | import static android.content.ContentValues.TAG; 10 | import static fr.ec.producthunt.ui.home.PostsFragments.SyncPostReceiver.ACTION_LOAD_POSTS; 11 | 12 | /** 13 | * An {@link IntentService} subclass for handling asynchronous task requests in 14 | * a service on a separate handler thread. 15 | */ 16 | public class SyncService extends IntentService { 17 | private static final String ACTION_FETCH_NEW_POSTS = 18 | "fr.ec.producthunt.data.action.FETCH_NEW_POSTS"; 19 | 20 | public SyncService() { 21 | super("SyncService"); 22 | } 23 | 24 | @Override public void onCreate() { 25 | super.onCreate(); 26 | } 27 | 28 | /** 29 | * Starts this service to perform action Foo with the given parameters. If 30 | * the service is already performing a task this action will be queued. 31 | * 32 | * @see IntentService 33 | */ 34 | public static void startSyncPosts(Context context) { 35 | Intent intent = new Intent(context, SyncService.class); 36 | intent.setAction(ACTION_FETCH_NEW_POSTS); 37 | context.startService(intent); 38 | } 39 | 40 | @Override protected void onHandleIntent(Intent intent) { 41 | if (intent != null) { 42 | final String action = intent.getAction(); 43 | if (ACTION_FETCH_NEW_POSTS.equals(action)) { 44 | handleActionFetchNewPosts(); 45 | Log.d(TAG, "handleActionFetchNewPosts is Ok"); 46 | } 47 | } 48 | } 49 | 50 | /** 51 | * Handle action Foo in the provided background thread with the provided 52 | * parameters. 53 | */ 54 | private void handleActionFetchNewPosts() { 55 | 56 | DataProvider.getInstance(this.getApplication()).syncPost(); 57 | Intent intentToSend = new Intent(); 58 | intentToSend.setAction(ACTION_LOAD_POSTS); 59 | LocalBroadcastManager.getInstance(this).sendBroadcast(intentToSend); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 15 | 16 | 22 | 23 | 33 | 34 | 43 | 44 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/ui/home/PostAdapter.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.home; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | import android.widget.BaseAdapter; 7 | import android.widget.ImageView; 8 | import android.widget.TextView; 9 | import com.squareup.picasso.Picasso; 10 | import fr.ec.producthunt.R; 11 | import fr.ec.producthunt.data.model.Post; 12 | import java.util.Collections; 13 | import java.util.List; 14 | 15 | public class PostAdapter extends BaseAdapter { 16 | 17 | private List dataSource = Collections.emptyList(); 18 | 19 | public PostAdapter() { 20 | } 21 | 22 | @Override public int getCount() { 23 | return dataSource.size(); 24 | } 25 | 26 | @Override public Object getItem(int position) { 27 | return dataSource.get(position); 28 | } 29 | 30 | @Override public long getItemId(int position) { 31 | return position; 32 | } 33 | 34 | @Override public View getView(int position, View convertView, ViewGroup parent) { 35 | 36 | ViewHolder viewHolder; 37 | 38 | if (convertView == null) { 39 | convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); 40 | 41 | viewHolder = new ViewHolder(); 42 | viewHolder.title = convertView.findViewById(R.id.title); 43 | viewHolder.subTitle = convertView.findViewById(R.id.sub_title); 44 | viewHolder.postImage = convertView.findViewById(R.id.img_product); 45 | 46 | convertView.setTag(viewHolder); 47 | } else { 48 | 49 | viewHolder = (ViewHolder) convertView.getTag(); 50 | } 51 | 52 | Post post = dataSource.get(position); 53 | viewHolder.title.setText(post.getTitle()); 54 | viewHolder.subTitle.setText(post.getSubTitle()); 55 | 56 | 57 | Picasso.with(parent.getContext()) 58 | .load(post.getImageUrl()) 59 | .centerCrop() 60 | .fit() 61 | .into(viewHolder.postImage); 62 | 63 | return convertView; 64 | } 65 | 66 | public void showPosts(List posts) { 67 | dataSource = posts; 68 | 69 | notifyDataSetChanged(); 70 | } 71 | 72 | private static class ViewHolder { 73 | TextView title; 74 | TextView subTitle; 75 | ImageView postImage; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /OLD/app/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /OLD/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/ui/detail/DetailPostFragment.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.detail; 2 | 3 | import android.graphics.Bitmap; 4 | import android.os.Bundle; 5 | import androidx.annotation.Nullable; 6 | import androidx.fragment.app.Fragment; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.webkit.WebView; 11 | import android.webkit.WebViewClient; 12 | import android.widget.ViewAnimator; 13 | import fr.ec.producthunt.R; 14 | 15 | public class DetailPostFragment extends Fragment { 16 | 17 | public static final String URL_KEY = "URL_KEY"; 18 | private static final int PROGRESS_CHILD = 0; 19 | private static final int WEBVIEW_CHILD = 1; 20 | 21 | String postUrl; 22 | private WebView webView; 23 | private ViewAnimator viewAnimator; 24 | 25 | public static Fragment getNewInstance(String url) { 26 | Fragment fragment = new DetailPostFragment(); 27 | Bundle bundle = new Bundle(); 28 | bundle.putString(URL_KEY, url); 29 | ; 30 | fragment.setArguments(bundle); 31 | 32 | return fragment; 33 | } 34 | 35 | @Override public void onCreate(@Nullable Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | postUrl = getArguments().getString(URL_KEY); 38 | } 39 | 40 | @Nullable @Override 41 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 42 | @Nullable Bundle savedInstanceState) { 43 | 44 | View rootView = inflater.inflate(R.layout.detail_post_fragment, container, false); 45 | 46 | webView = rootView.findViewById(R.id.detail_webview); 47 | 48 | viewAnimator = rootView.findViewById(R.id.detail_viewanimator); 49 | viewAnimator.setDisplayedChild(PROGRESS_CHILD); 50 | 51 | webView.getSettings().setJavaScriptEnabled(true); 52 | webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); 53 | webView.setWebViewClient(new WebViewClient() { 54 | 55 | @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { 56 | view.loadUrl(url); 57 | return true; 58 | } 59 | 60 | @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { 61 | super.onPageStarted(view, url, favicon); 62 | viewAnimator.setDisplayedChild(PROGRESS_CHILD); 63 | } 64 | 65 | @Override public void onPageFinished(WebView view, String url) { 66 | super.onPageFinished(view, url); 67 | viewAnimator.setDisplayedChild(WEBVIEW_CHILD); 68 | } 69 | }); 70 | 71 | if (postUrl != null) { 72 | webView.loadUrl(postUrl); 73 | }else { 74 | viewAnimator.setDisplayedChild(WEBVIEW_CHILD); 75 | } 76 | return rootView; 77 | } 78 | 79 | public void loadUrl(String postUrl) { 80 | this.postUrl = postUrl; 81 | viewAnimator.setDisplayedChild(PROGRESS_CHILD); 82 | webView.loadUrl(this.postUrl); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/ui/detail/DetailPostFragment.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.detail; 2 | 3 | import android.graphics.Bitmap; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.webkit.WebView; 11 | import android.webkit.WebViewClient; 12 | import android.widget.ViewAnimator; 13 | import fr.ec.producthunt.R; 14 | 15 | public class DetailPostFragment extends Fragment { 16 | 17 | public static final String URL_KEY = "URL_KEY"; 18 | private static final int PROGRESS_CHILD = 0; 19 | private static final int WEBVIEW_CHILD = 1; 20 | 21 | String postUrl; 22 | private WebView webView; 23 | private ViewAnimator viewAnimator; 24 | 25 | public static Fragment getNewInstance(String url) { 26 | Fragment fragment = new DetailPostFragment(); 27 | Bundle bundle = new Bundle(); 28 | bundle.putString(URL_KEY, url); 29 | ; 30 | fragment.setArguments(bundle); 31 | 32 | return fragment; 33 | } 34 | 35 | @Override public void onCreate(@Nullable Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | postUrl = getArguments().getString(URL_KEY); 38 | } 39 | 40 | @Nullable @Override 41 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 42 | @Nullable Bundle savedInstanceState) { 43 | 44 | View rootView = inflater.inflate(R.layout.detail_post_fragment, container, false); 45 | 46 | webView = rootView.findViewById(R.id.detail_webview); 47 | 48 | viewAnimator = rootView.findViewById(R.id.detail_viewanimator); 49 | viewAnimator.setDisplayedChild(PROGRESS_CHILD); 50 | 51 | webView.getSettings().setJavaScriptEnabled(true); 52 | webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); 53 | webView.setWebViewClient(new WebViewClient() { 54 | 55 | @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { 56 | view.loadUrl(url); 57 | return true; 58 | } 59 | 60 | @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { 61 | super.onPageStarted(view, url, favicon); 62 | viewAnimator.setDisplayedChild(PROGRESS_CHILD); 63 | } 64 | 65 | @Override public void onPageFinished(WebView view, String url) { 66 | super.onPageFinished(view, url); 67 | viewAnimator.setDisplayedChild(WEBVIEW_CHILD); 68 | } 69 | }); 70 | 71 | if (postUrl != null) { 72 | webView.loadUrl(postUrl); 73 | }else { 74 | viewAnimator.setDisplayedChild(WEBVIEW_CHILD); 75 | } 76 | return rootView; 77 | } 78 | 79 | public void loadUrl(String postUrl) { 80 | this.postUrl = postUrl; 81 | viewAnimator.setDisplayedChild(PROGRESS_CHILD); 82 | webView.loadUrl(this.postUrl); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/ui/home/MainActivity.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.home; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.Nullable; 7 | import androidx.appcompat.app.ActionBarDrawerToggle; 8 | import androidx.appcompat.app.AppCompatActivity; 9 | import androidx.appcompat.widget.Toolbar; 10 | import androidx.core.view.GravityCompat; 11 | import androidx.drawerlayout.widget.DrawerLayout; 12 | 13 | import android.view.MenuItem; 14 | import android.widget.FrameLayout; 15 | 16 | import com.google.android.material.navigation.NavigationView; 17 | 18 | import fr.ec.producthunt.R; 19 | import fr.ec.producthunt.data.model.Post; 20 | import fr.ec.producthunt.ui.detail.DetailActivity; 21 | import fr.ec.producthunt.ui.detail.DetailPostFragment; 22 | 23 | public class MainActivity extends AppCompatActivity implements PostsFragments.Callback, NavigationView.OnNavigationItemSelectedListener { 24 | 25 | private boolean towPane; 26 | 27 | @Override 28 | protected void onCreate(@Nullable Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.main_activity); 31 | 32 | FrameLayout detailContainer = findViewById(R.id.home_detail_container); 33 | 34 | if (detailContainer != null) { 35 | towPane = true; 36 | getSupportFragmentManager().beginTransaction() 37 | .add(R.id.home_detail_container, DetailPostFragment.getNewInstance(null)) 38 | .commit(); 39 | } 40 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 41 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 42 | ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( 43 | this, drawer, toolbar, R.string.navigation_drawer_open, 44 | R.string.navigation_drawer_close 45 | ); 46 | drawer.setDrawerListener(toggle); 47 | toggle.syncState(); 48 | 49 | NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); 50 | navigationView.setNavigationItemSelectedListener(this); 51 | } 52 | 53 | @Override 54 | public void onClickPost(Post post) { 55 | 56 | if (towPane) { 57 | DetailPostFragment detailPostFragment = 58 | (DetailPostFragment) getSupportFragmentManager().findFragmentById(R.id.home_detail_container); 59 | 60 | if (detailPostFragment != null) { 61 | detailPostFragment.loadUrl(post.getPostUrl()); 62 | } 63 | } else { 64 | 65 | Intent intent = new Intent(this, DetailActivity.class); 66 | intent.putExtra(DetailActivity.POST_URL_KEY, post.getPostUrl()); 67 | 68 | startActivity(intent); 69 | } 70 | } 71 | 72 | @Override 73 | public boolean onNavigationItemSelected(MenuItem item) { 74 | // Handle navigation view item clicks here. 75 | int id = item.getItemId(); 76 | 77 | /*if (id == R.id.nav_camera) { 78 | // Handle the camera action 79 | } else if (id == R.id.nav_share) { 80 | 81 | } else if (id == R.id.nav_send) { 82 | 83 | }*/ 84 | 85 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 86 | drawer.closeDrawer(GravityCompat.START); 87 | return true; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/data/DataProvider.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.data; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | import fr.ec.producthunt.data.database.PostDao; 6 | import fr.ec.producthunt.data.database.ProductHuntDbHelper; 7 | import fr.ec.producthunt.data.model.Post; 8 | import java.io.BufferedReader; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.io.InputStreamReader; 12 | import java.net.HttpURLConnection; 13 | import java.net.URL; 14 | import java.util.List; 15 | 16 | import static android.content.ContentValues.TAG; 17 | 18 | public class DataProvider { 19 | 20 | public static final String POST_API_END_POINT = 21 | "https://api.producthunt.com/v1/posts?access_token=46a03e1c32ea881c8afb39e59aa17c936ff4205a8ed418f525294b2b45b56abb"; 22 | 23 | private JsonPostParser jsonPostParser = new JsonPostParser(); 24 | 25 | private final PostDao postDao; 26 | 27 | private static DataProvider dataProvider; 28 | 29 | public static DataProvider getInstance(Application application) { 30 | 31 | if (dataProvider == null) { 32 | dataProvider = new DataProvider(ProductHuntDbHelper.getInstance(application)); 33 | } 34 | return dataProvider; 35 | } 36 | 37 | public DataProvider(ProductHuntDbHelper dbHelper) { 38 | postDao = new PostDao(dbHelper); 39 | } 40 | 41 | private String getPostsFromWeb(String apiUrl) { 42 | 43 | HttpURLConnection urlConnection = null; 44 | BufferedReader reader = null; 45 | 46 | // Contiendra la réponse JSON brute sous forme de String . 47 | String posts = null; 48 | 49 | try { 50 | // Construire l' URL de l'API ProductHunt 51 | URL url = new URL(apiUrl); 52 | 53 | // Creer de la requête http vers l'API ProductHunt , et ouvrir la connexion 54 | urlConnection = (HttpURLConnection) url.openConnection(); 55 | urlConnection.setRequestMethod("GET"); 56 | urlConnection.connect(); 57 | 58 | // Lire le input stream et le convertir String 59 | InputStream inputStream = urlConnection.getInputStream(); 60 | StringBuffer buffer = new StringBuffer(); 61 | if (inputStream == null) { 62 | // Nothing to do. 63 | return null; 64 | } 65 | reader = new BufferedReader(new InputStreamReader(inputStream)); 66 | 67 | String line; 68 | while ((line = reader.readLine()) != null) { 69 | buffer.append(line + "\n"); 70 | } 71 | 72 | if (buffer.length() == 0) { 73 | // Si le stream est vide, on revoie null; 74 | return null; 75 | } 76 | posts = buffer.toString(); 77 | } catch (IOException e) { 78 | Log.e(TAG, "Error ", e); 79 | return null; 80 | } finally { 81 | if (urlConnection != null) { 82 | urlConnection.disconnect(); 83 | } 84 | if (reader != null) { 85 | try { 86 | reader.close(); 87 | } catch (final IOException e) { 88 | Log.e(TAG, "Error closing stream", e); 89 | } 90 | } 91 | } 92 | 93 | return posts; 94 | } 95 | 96 | public List getPostsFromDatabase() { 97 | return postDao.retrievePosts(); 98 | } 99 | 100 | 101 | public Boolean syncPost() { 102 | 103 | List list = jsonPostParser.jsonToPosts(getPostsFromWeb(POST_API_END_POINT)); 104 | 105 | 106 | int nb = 0; 107 | 108 | for (Post post : list) { 109 | postDao.save(post); 110 | nb++; 111 | } 112 | return nb > 0; 113 | } 114 | } 115 | 116 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/ui/home/PostAdapter.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.home; 2 | 3 | import android.util.Log; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.ImageView; 9 | import android.widget.TextView; 10 | import com.squareup.picasso.Picasso; 11 | import fr.ec.producthunt.R; 12 | import fr.ec.producthunt.data.model.Post; 13 | import java.util.Collections; 14 | import java.util.List; 15 | 16 | import static android.content.ContentValues.TAG; 17 | 18 | public class PostAdapter extends BaseAdapter { 19 | 20 | private List dataSource = Collections.emptyList(); 21 | 22 | public PostAdapter() { 23 | } 24 | 25 | @Override public int getCount() { 26 | return dataSource.size(); 27 | } 28 | 29 | @Override public Object getItem(int position) { 30 | return dataSource.get(position); 31 | } 32 | 33 | @Override public long getItemId(int position) { 34 | return position; 35 | } 36 | 37 | @Override public View getView(int position, View convertView, ViewGroup parent) { 38 | 39 | ViewHolder viewHolder; 40 | 41 | boolean isBigView = getViewType(position); 42 | 43 | if(!isBigView) { 44 | if (convertView == null) { 45 | convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); 46 | 47 | viewHolder = new ViewHolder(); 48 | viewHolder.title = convertView.findViewById(R.id.title); 49 | viewHolder.subTitle = convertView.findViewById(R.id.sub_title); 50 | viewHolder.postImage = convertView.findViewById(R.id.img_product); 51 | viewHolder.commentsNumber = convertView.findViewById(R.id.comments_counter); 52 | 53 | 54 | convertView.setTag(viewHolder); 55 | } else { 56 | 57 | viewHolder = (ViewHolder) convertView.getTag(); 58 | } 59 | 60 | Post post = dataSource.get(position); 61 | viewHolder.title.setText(post.getTitle()); 62 | viewHolder.subTitle.setText(post.getSubTitle()); 63 | Log.d(TAG, "getView: "+ post.getCommentNumber()); 64 | viewHolder.commentsNumber.setText(post.getCommentNumber() + " comments"); 65 | 66 | 67 | Picasso.with(parent.getContext()) 68 | .load(post.getImageUrl()) 69 | .centerCrop() 70 | .fit() 71 | .into(viewHolder.postImage); 72 | } else { 73 | if (convertView == null) { 74 | convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_item, parent, false); 75 | 76 | viewHolder = new ViewHolder(); 77 | viewHolder.title = convertView.findViewById(R.id.title); 78 | viewHolder.subTitle = convertView.findViewById(R.id.sub_title); 79 | viewHolder.postImage = convertView.findViewById(R.id.img_product); 80 | viewHolder.commentsNumber = convertView.findViewById(R.id.comments_counter); 81 | 82 | convertView.setTag(viewHolder); 83 | } else { 84 | 85 | viewHolder = (ViewHolder) convertView.getTag(); 86 | } 87 | 88 | Post post = dataSource.get(position); 89 | viewHolder.title.setText(post.getTitle()); 90 | viewHolder.subTitle.setText(post.getSubTitle()); 91 | viewHolder.commentsNumber.setText(post.getCommentNumber() + " comments"); 92 | 93 | 94 | Picasso.with(parent.getContext()) 95 | .load(post.getImageUrl()) 96 | .centerCrop() 97 | .fit() 98 | .into(viewHolder.postImage); 99 | } 100 | 101 | 102 | 103 | return convertView; 104 | } 105 | 106 | private boolean getViewType(int itemPosition) { 107 | return itemPosition == 0; 108 | } 109 | 110 | public void showPosts(List posts) { 111 | dataSource = posts; 112 | 113 | notifyDataSetChanged(); 114 | } 115 | 116 | private static class ViewHolder { 117 | TextView title; 118 | TextView subTitle; 119 | TextView commentsNumber; 120 | ImageView postImage; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /OLD/app/src/main/java/fr/ec/producthunt/ui/home/PostsFragments.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.home; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.os.AsyncTask; 8 | import android.os.Bundle; 9 | import androidx.annotation.Nullable; 10 | import androidx.fragment.app.Fragment; 11 | import androidx.localbroadcastmanager.content.LocalBroadcastManager; 12 | import android.view.LayoutInflater; 13 | import android.view.Menu; 14 | import android.view.MenuInflater; 15 | import android.view.MenuItem; 16 | import android.view.View; 17 | import android.view.ViewGroup; 18 | import android.widget.AdapterView; 19 | import android.widget.ListView; 20 | import android.widget.ViewAnimator; 21 | import fr.ec.producthunt.R; 22 | import fr.ec.producthunt.data.DataProvider; 23 | import fr.ec.producthunt.data.SyncService; 24 | import fr.ec.producthunt.data.model.Post; 25 | import java.util.List; 26 | 27 | public class PostsFragments extends Fragment { 28 | 29 | private static final int PROGRESS_CHILD = 1; 30 | private static final int LIST_CHILD = 0; 31 | 32 | private DataProvider dataProvider; 33 | private PostAdapter postAdapter; 34 | private ViewAnimator viewAnimator; 35 | 36 | private SyncPostReceiver syncPostReceiver; 37 | 38 | private Callback callback; 39 | 40 | @Override public void onCreate(@Nullable Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | this.setHasOptionsMenu(true); 43 | } 44 | 45 | @Override public void onAttach(Context context) { 46 | super.onAttach(context); 47 | callback = (Callback) getActivity(); 48 | } 49 | 50 | @Nullable @Override 51 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 52 | @Nullable Bundle savedInstanceState) { 53 | 54 | View rootView = inflater.inflate(R.layout.home_post_list_fragment,container,false); 55 | 56 | syncPostReceiver = new SyncPostReceiver(); 57 | 58 | postAdapter = new PostAdapter(); 59 | 60 | ListView listView = rootView.findViewById(R.id.list_item); 61 | listView.setEmptyView(rootView.findViewById(R.id.empty_element)); 62 | 63 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 64 | @Override public void onItemClick(AdapterView parent, View view, int position, long id) { 65 | 66 | Post post = (Post) parent.getAdapter().getItem(position); 67 | callback.onClickPost(post); 68 | 69 | } 70 | }); 71 | viewAnimator = rootView.findViewById(R.id.main_view_animator); 72 | listView.setAdapter(postAdapter); 73 | 74 | return rootView; 75 | } 76 | 77 | @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { 78 | super.onActivityCreated(savedInstanceState); 79 | dataProvider = DataProvider.getInstance(getActivity().getApplication()); 80 | loadPosts(); 81 | } 82 | 83 | @Override public void onStart() { 84 | super.onStart(); 85 | IntentFilter intentFilter = new IntentFilter(); 86 | intentFilter.addAction(SyncPostReceiver.ACTION_LOAD_POSTS); 87 | LocalBroadcastManager.getInstance(this.getContext()) 88 | .registerReceiver(syncPostReceiver, intentFilter); 89 | } 90 | 91 | @Override public void onStop() { 92 | super.onStop(); 93 | LocalBroadcastManager.getInstance(this.getContext()).unregisterReceiver(syncPostReceiver); 94 | } 95 | 96 | @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 97 | 98 | inflater.inflate(R.menu.main, menu); 99 | } 100 | 101 | @Override public boolean onOptionsItemSelected(MenuItem item) { 102 | switch (item.getItemId()) { 103 | 104 | case R.id.refresh: 105 | refreshPosts(); 106 | return true; 107 | default: 108 | return super.onOptionsItemSelected(item); 109 | } 110 | } 111 | 112 | public class SyncPostReceiver extends BroadcastReceiver { 113 | public static final String ACTION_LOAD_POSTS = "fr.ec.producthunt.data.action.LOAD_POSTS"; 114 | 115 | public SyncPostReceiver() { 116 | } 117 | 118 | @Override public void onReceive(Context context, Intent intent) { 119 | if (intent != null && intent.getAction().equals(ACTION_LOAD_POSTS)) { 120 | loadPosts(); 121 | } 122 | } 123 | } 124 | 125 | private void refreshPosts() { 126 | SyncService.startSyncPosts(getContext()); 127 | } 128 | 129 | private void loadPosts() { 130 | FetchPostsAsyncTask fetchPstsAsyncTask = new FetchPostsAsyncTask(); 131 | fetchPstsAsyncTask.execute(); 132 | } 133 | 134 | private class FetchPostsAsyncTask extends AsyncTask> { 135 | 136 | @Override protected void onPreExecute() { 137 | super.onPreExecute(); 138 | viewAnimator.setDisplayedChild(PROGRESS_CHILD); 139 | } 140 | 141 | @Override protected List doInBackground(Void... params) { 142 | 143 | return dataProvider.getPostsFromDatabase(); 144 | } 145 | 146 | @Override protected void onPostExecute(List posts) { 147 | if (posts != null && !posts.isEmpty()) { 148 | postAdapter.showPosts(posts); 149 | } 150 | viewAnimator.setDisplayedChild(LIST_CHILD); 151 | } 152 | } 153 | 154 | public interface Callback { 155 | void onClickPost(Post post); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /app/src/main/java/fr/ec/producthunt/ui/home/PostsFragments.java: -------------------------------------------------------------------------------- 1 | package fr.ec.producthunt.ui.home; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.os.AsyncTask; 8 | import android.os.Bundle; 9 | import android.support.annotation.Nullable; 10 | import android.support.v4.app.Fragment; 11 | import android.support.v4.content.LocalBroadcastManager; 12 | import android.view.LayoutInflater; 13 | import android.view.Menu; 14 | import android.view.MenuInflater; 15 | import android.view.MenuItem; 16 | import android.view.View; 17 | import android.view.ViewGroup; 18 | import android.widget.AdapterView; 19 | import android.widget.ListView; 20 | import android.widget.ViewAnimator; 21 | import fr.ec.producthunt.R; 22 | import fr.ec.producthunt.data.DataProvider; 23 | import fr.ec.producthunt.data.SyncService; 24 | import fr.ec.producthunt.data.model.Post; 25 | import fr.ec.producthunt.ui.detail.DetailActivity; 26 | import java.util.List; 27 | 28 | public class PostsFragments extends Fragment { 29 | 30 | private static final int PROGRESS_CHILD = 1; 31 | private static final int LIST_CHILD = 0; 32 | 33 | private DataProvider dataProvider; 34 | private PostAdapter postAdapter; 35 | private ViewAnimator viewAnimator; 36 | 37 | private SyncPostReceiver syncPostReceiver; 38 | 39 | private Callback callback; 40 | 41 | @Override public void onCreate(@Nullable Bundle savedInstanceState) { 42 | super.onCreate(savedInstanceState); 43 | this.setHasOptionsMenu(true); 44 | } 45 | 46 | @Override public void onAttach(Context context) { 47 | super.onAttach(context); 48 | callback = (Callback) getActivity(); 49 | } 50 | 51 | @Nullable @Override 52 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 53 | @Nullable Bundle savedInstanceState) { 54 | 55 | View rootView = inflater.inflate(R.layout.home_post_list_fragment,container,false); 56 | 57 | syncPostReceiver = new SyncPostReceiver(); 58 | 59 | postAdapter = new PostAdapter(); 60 | 61 | ListView listView = rootView.findViewById(R.id.list_item); 62 | listView.setEmptyView(rootView.findViewById(R.id.empty_element)); 63 | 64 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 65 | @Override public void onItemClick(AdapterView parent, View view, int position, long id) { 66 | 67 | Post post = (Post) parent.getAdapter().getItem(position); 68 | callback.onClickPost(post); 69 | 70 | } 71 | }); 72 | viewAnimator = rootView.findViewById(R.id.main_view_animator); 73 | listView.setAdapter(postAdapter); 74 | 75 | return rootView; 76 | } 77 | 78 | @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { 79 | super.onActivityCreated(savedInstanceState); 80 | dataProvider = DataProvider.getInstance(getActivity().getApplication()); 81 | loadPosts(); 82 | } 83 | 84 | @Override public void onStart() { 85 | super.onStart(); 86 | IntentFilter intentFilter = new IntentFilter(); 87 | intentFilter.addAction(SyncPostReceiver.ACTION_LOAD_POSTS); 88 | LocalBroadcastManager.getInstance(this.getContext()) 89 | .registerReceiver(syncPostReceiver, intentFilter); 90 | } 91 | 92 | @Override public void onStop() { 93 | super.onStop(); 94 | LocalBroadcastManager.getInstance(this.getContext()).unregisterReceiver(syncPostReceiver); 95 | } 96 | 97 | @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 98 | 99 | inflater.inflate(R.menu.main, menu); 100 | } 101 | 102 | @Override public boolean onOptionsItemSelected(MenuItem item) { 103 | switch (item.getItemId()) { 104 | 105 | case R.id.refresh: 106 | refreshPosts(); 107 | return true; 108 | default: 109 | return super.onOptionsItemSelected(item); 110 | } 111 | } 112 | 113 | public class SyncPostReceiver extends BroadcastReceiver { 114 | public static final String ACTION_LOAD_POSTS = "fr.ec.producthunt.data.action.LOAD_POSTS"; 115 | 116 | public SyncPostReceiver() { 117 | } 118 | 119 | @Override public void onReceive(Context context, Intent intent) { 120 | if (intent != null && intent.getAction().equals(ACTION_LOAD_POSTS)) { 121 | loadPosts(); 122 | } 123 | } 124 | } 125 | 126 | private void refreshPosts() { 127 | SyncService.startSyncPosts(getContext()); 128 | } 129 | 130 | private void loadPosts() { 131 | FetchPostsAsyncTask fetchPstsAsyncTask = new FetchPostsAsyncTask(); 132 | fetchPstsAsyncTask.execute(); 133 | } 134 | 135 | private class FetchPostsAsyncTask extends AsyncTask> { 136 | 137 | @Override protected void onPreExecute() { 138 | super.onPreExecute(); 139 | viewAnimator.setDisplayedChild(PROGRESS_CHILD); 140 | } 141 | 142 | @Override protected List doInBackground(Void... params) { 143 | 144 | return dataProvider.getPostsFromDatabase(); 145 | } 146 | 147 | @Override protected void onPostExecute(List posts) { 148 | if (posts != null && !posts.isEmpty()) { 149 | postAdapter.showPosts(posts); 150 | } 151 | viewAnimator.setDisplayedChild(LIST_CHILD); 152 | } 153 | } 154 | 155 | public interface Callback { 156 | void onClickPost(Post post); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /OLD/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 172 | -------------------------------------------------------------------------------- /OLD/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 172 | -------------------------------------------------------------------------------- /OLD/app/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | --------------------------------------------------------------------------------