Unverified Commit cc7d05fb authored by Tamás Szabó's avatar Tamás Szabó Committed by GitHub
Browse files

Merge pull request #12 from szakitom/development

finished labor 6
parents 1c6f2322 3ddcf7f2
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="imageAssetPanel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="launcher">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="foregroundImage">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="scalingPercent" value="70" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="backgroundAssetType" value="COLOR" />
<entry key="backgroundColor" value="ffffff" />
<entry key="foregroundImage" value="$USER_HOME$/Downloads/512x512bb.jpg" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>
\ No newline at end of file
......@@ -24,7 +24,7 @@
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
......
language: android
android:
components:
- build-tools-26.0.2
- build-tools-27.0.3
- android-22
- android-26
- add-on
- extra
- platform-tools
- tools
- extra-google-googleplayservices
- platform-tools
- build-tools-27.0.3
- android-22
- android-27
- extra-google-google_play_services
- extra-google-m2repository
- extra-android-m2repository
- addon-google_apis-google-26
- addon-google_apis-google-27
- sys-img-armeabi-v7a-android-22
env:
global:
- MALLOC_ARENA_MAX=2
......@@ -21,7 +21,7 @@ env:
sudo: required
before_install:
- yes | sdkmanager "platforms;android-26"
- yes | sdkmanager "platforms;android-27"
before_script:
- echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a
......
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
compileSdkVersion 27
defaultConfig {
applicationId "me.szaki.xkcd.xkcdbrowser"
minSdkVersion 22
targetSdkVersion 26
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
......@@ -55,17 +55,18 @@ ext {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
// Dagger
implementation 'com.google.dagger:dagger:2.11'
implementation 'com.google.dagger:dagger-android-support:2.11' // if you use the support libraries
implementation 'com.google.dagger:dagger-android-support:2.11'
// if you use the support libraries
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.11'
implementation 'com.google.dagger:dagger-android:2.11'
......@@ -82,5 +83,16 @@ dependencies {
// Room
implementation 'android.arch.persistence.room:runtime:1.0.0'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
}
// AndroidSwipeLayout
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
//Unit Test - Robolectric
//JUnit - JUnit 5 is not supported yet
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:3.7.1'
testImplementation 'org.mockito:mockito-core:2.15.0'
testImplementation 'com.google.dagger:dagger:2.11'
testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.11'
testCompileOnly 'javax.annotation:jsr250-api:1.0'
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="me.szaki.xkcd.xkcdbrowser">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".XKCDBrowserApplication"
android:allowBackup="true"
......@@ -10,15 +12,29 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".ui.main.MainActivity">
<activity
android:name=".ui.main.MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ui.detail.DetailActivity"></activity>
<activity android:name=".ui.favorites.FavoritesActivity"></activity>
<activity
android:name=".ui.favorites.FavoritesActivity"
android:label="@string/title_activity_favorites"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".ui.detail.DetailActivity"
android:label="@string/title_activity_detail"
android:parentActivityName=".ui.favorites.FavoritesActivity"
android:theme="@style/AppTheme.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="me.szaki.xkcd.xkcdbrowser.ui.favorites.FavoritesActivity" />
</activity>
</application>
</manifest>
\ No newline at end of file
......@@ -7,6 +7,7 @@ import dagger.Component;
import me.szaki.xkcd.xkcdbrowser.database.DBModule;
import me.szaki.xkcd.xkcdbrowser.interactor.InteractorModule;
import me.szaki.xkcd.xkcdbrowser.interactor.comics.ComicsInteractor;
import me.szaki.xkcd.xkcdbrowser.interactor.comics.DBInteractor;
import me.szaki.xkcd.xkcdbrowser.network.NetworkModule;
import me.szaki.xkcd.xkcdbrowser.ui.UIModule;
import me.szaki.xkcd.xkcdbrowser.ui.detail.DetailActivity;
......@@ -33,4 +34,6 @@ public interface XKCDBrowserApplicationComponent {
void inject(FavoritesPresenter favoritesPresenter);
void inject(ComicsInteractor comicsInteractor);
void inject(DBInteractor dbInteractor);
}
package me.szaki.xkcd.xkcdbrowser.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import me.szaki.xkcd.xkcdbrowser.R;
import me.szaki.xkcd.xkcdbrowser.model.ComicStrip;
public class FavoriteListAdapter extends RecyclerView.Adapter<FavoriteListAdapter.ViewHolder> {
private List<ComicStrip> comicStrips;
private static ClickListener clickListener;
public FavoriteListAdapter() {
super();
this.comicStrips = new ArrayList<>();
}
static class ViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public TextView date;
public ViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title_text);
date = itemView.findViewById(R.id.date_text);
itemView.findViewById(R.id.delete_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (FavoriteListAdapter.clickListener != null)
FavoriteListAdapter.clickListener.onDeleteClick(getAdapterPosition(), view);
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if (FavoriteListAdapter.clickListener != null)
FavoriteListAdapter.clickListener.onClick(getAdapterPosition(), view);
return false;
}
});
}
}
public interface ClickListener {
void onClick(int position, View v);
void onDeleteClick(int position, View v);
}
@Override
public FavoriteListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.comic_strip, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(FavoriteListAdapter.ViewHolder holder, int position) {
ComicStrip comicStrip = this.comicStrips.get(position);
holder.title.setText(comicStrip.getTitle());
holder.date.setText(String.format("%s.%02d.%02d.", comicStrip.getYear(), Integer.parseInt(comicStrip.getMonth()), Integer.parseInt(comicStrip.getDay())));
}
@Override
public int getItemCount() {
return this.comicStrips.size();
}
public void updateList(List<ComicStrip> cList) {
this.comicStrips = cList;
this.notifyDataSetChanged();
}
public void setListener(ClickListener clickListener) {
this.clickListener = clickListener;
}
public ComicStrip getComicStripByNum(int position) {
return this.comicStrips.get(position);
}
}
......@@ -18,6 +18,9 @@ public interface ComicsDAO {
@Query("SELECT * FROM ComicStrip WHERE id = :id")
public ComicStrip getComic(Long id);
@Query("SELECT * FROM ComicStrip WHERE num = :num")
public ComicStrip getComicByNum(Long num);
@Insert
public void insertAll(ComicStrip... comic);
......
......@@ -2,8 +2,6 @@ package me.szaki.xkcd.xkcdbrowser.interactor.comics;
import java.io.IOException;
import java.util.Date;
import java.util.Random;
import javax.inject.Inject;
......@@ -23,12 +21,8 @@ public class ComicsInteractor {
return this.comicApi.getComic(id).execute().body();
}
public Comic getRandomComic() throws IOException {
Random r = new Random(new Date().getTime());
return this.comicApi.getComic(r.nextLong()).execute().body();
}
public Comic getLatestComic() throws IOException {
return this.comicApi.getCurrentComic().execute().body();
}
}
......@@ -6,6 +6,7 @@ import java.util.Random;
import javax.inject.Inject;
import me.szaki.xkcd.xkcdbrowser.XKCDBrowserApplication;
import me.szaki.xkcd.xkcdbrowser.database.ComicsDatabase;
import me.szaki.xkcd.xkcdbrowser.model.ComicStrip;
......@@ -13,6 +14,10 @@ public class DBInteractor {
@Inject
ComicsDatabase db;
public DBInteractor() {
XKCDBrowserApplication.injector.inject(this);
}
public List<ComicStrip> getComics() {
return db.getDAO().getAllComics();
}
......@@ -29,5 +34,6 @@ public class DBInteractor {
db.getDAO().insertAll(c);
}
public ComicStrip getComicByNum(Long id) { return db.getDAO().getComicByNum(id); }
}
package me.szaki.xkcd.xkcdbrowser.ui.detail;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.ImageView;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.inject.Inject;
import me.szaki.xkcd.xkcdbrowser.R;
import me.szaki.xkcd.xkcdbrowser.XKCDBrowserApplication;
import me.szaki.xkcd.xkcdbrowser.model.ComicStrip;
public class DetailActivity extends AppCompatActivity implements DetailScreen {
@Inject
DetailPresenter detailPresenter;
private ImageView detailImageView;
private Long num;
public DetailActivity() {
XKCDBrowserApplication.injector.inject(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
XKCDBrowserApplication.injector.inject(this);
this.detailImageView = findViewById(R.id.detailImageView);
Intent i = getIntent();
num = i.getLongExtra("num", 0l);
}
@Override
protected void onStart() {
super.onStart();
detailPresenter.attachScreen(this);
this.detailPresenter.attachScreen(this);
detailPresenter.getComicByNum(Long.valueOf(num));
}
@Override
protected void onStop() {
super.onStop();
detailPresenter.detachScreen();
this.detailPresenter.detachScreen();
}
@Override
public void dataReceived(final ComicStrip comic) {
Handler mainHandler = new Handler(getApplicationContext().getMainLooper());
Bitmap mIcon_val = null;
if (comic != null) {
try {
URL newurl = new URL(comic.getImg());
mIcon_val = BitmapFactory.decodeStream(newurl.openConnection().getInputStream());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
final Bitmap finalMIcon_val = mIcon_val;
Runnable myRunnable = new Runnable() {
@Override
public void run() {
detailImageView.setImageBitmap(finalMIcon_val);
setTitle(comic.getTitle());
}
};
mainHandler.post(myRunnable);
}
}
......@@ -4,24 +4,25 @@ package me.szaki.xkcd.xkcdbrowser.ui.detail;
import javax.inject.Inject;
import me.szaki.xkcd.xkcdbrowser.XKCDBrowserApplication;
import me.szaki.xkcd.xkcdbrowser.interactor.comics.ComicsInteractor;
import me.szaki.xkcd.xkcdbrowser.interactor.comics.DBInteractor;
import me.szaki.xkcd.xkcdbrowser.ui.Presenter;
public class DetailPresenter extends Presenter<DetailScreen> {
@Inject
ComicsInteractor comicsInteractor;
DBInteractor db;
public DetailPresenter () {
XKCDBrowserApplication.injector.inject(this);
}
@Override
public void attachScreen(DetailScreen screen) {
super.attachScreen(screen);
}
@Override
public void detachScreen() {
super.detachScreen();
public void getComicByNum(final Long id) {
new Thread() {
@Override
public void run() {
screen.dataReceived(db.getComicByNum(id));
}
}.start();
}
}
package me.szaki.xkcd.xkcdbrowser.ui.detail;
import java.util.List;
import me.szaki.xkcd.xkcdbrowser.model.ComicStrip;
public interface DetailScreen {
public void dataReceived(ComicStrip comic);
}
package me.szaki.xkcd.xkcdbrowser.ui.favorites;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import java.util.List;
import javax.inject.Inject;
import me.szaki.xkcd.xkcdbrowser.R;
import me.szaki.xkcd.xkcdbrowser.XKCDBrowserApplication;
import me.szaki.xkcd.xkcdbrowser.adapter.FavoriteListAdapter;
import me.szaki.xkcd.xkcdbrowser.model.ComicStrip;
import me.szaki.xkcd.xkcdbrowser.ui.detail.DetailActivity;
import me.szaki.xkcd.xkcdbrowser.ui.main.MainActivity;
public class FavoritesActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, FavoritesScreen, FavoriteListAdapter.ClickListener {
public class FavoritesActivity extends AppCompatActivity implements FavoritesScreen {
@Inject
FavoritesPresenter favoritesPresenter;
private FavoriteListAdapter mAdapter;
public FavoritesActivity() {
XKCDBrowserApplication.injector.inject(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_favorites);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
XKCDBrowserApplication.injector.inject(this);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
RecyclerView recyclerView = findViewById(R.id.strips);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
// use a linear layout manager
LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayout.VERTICAL));
// specify an adapter (see also next example)
mAdapter = new FavoriteListAdapter();
recyclerView.setAdapter(mAdapter);
mAdapter.setListener(this);