diff --git a/.gitignore b/.gitignore
index ccf2efe..d92797a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,3 @@
-# Built application files
-*.apk
-*.ap_
-
-# Files for the Dalvik VM
-*.dex
-
-# Java class files
-*.class
-
# Generated files
bin/
gen/
@@ -16,6 +6,7 @@ gen/
.gradle/
build/
/*/build/
+gradlew*
# Local configuration file (sdk path, etc)
local.properties
@@ -25,3 +16,7 @@ proguard/
# Log Files
*.log
+
+#android-studio file
+.idea
+*.iml
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..046b503
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 22
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "fr.mobdev.gobelim"
+ minSdkVersion 11
+ targetSdkVersion 22
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+}
diff --git a/app/src/androidTest/java/fr/mobdev/gobelim/ApplicationTest.java b/app/src/androidTest/java/fr/mobdev/gobelim/ApplicationTest.java
new file mode 100644
index 0000000..ab27f17
--- /dev/null
+++ b/app/src/androidTest/java/fr/mobdev/gobelim/ApplicationTest.java
@@ -0,0 +1,13 @@
+package fr.mobdev.gobelim;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8bb39a2
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/fr/mobdev/gobelim/Database.java b/app/src/main/java/fr/mobdev/gobelim/Database.java
new file mode 100644
index 0000000..f40a00e
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/Database.java
@@ -0,0 +1,162 @@
+package fr.mobdev.gobelim;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.TimeZone;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+
+import fr.mobdev.gobelim.objects.Img;
+import fr.mobdev.gobelim.objects.Server;
+
+public class Database extends SQLiteOpenHelper {
+
+ private static Database instance;
+
+ public static Database getInstance(Context context)
+ {
+ if(instance == null)
+ instance = new Database(context, "Lutim.db", null, 1);
+ return instance;
+ }
+
+ private Database(Context context, String name, CursorFactory factory, int version) {
+ super(context, name, factory, version);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("Create table if not exists history (" +
+ "id integer primary key autoincrement, url varchar(1024), short_hash varchar(1024), real_short_hash varchar(1024), date INTEGER, storage_duration INTEGER ,thumb TEXT);");
+ db.execSQL("Create table if not exists servers (" +
+ "id integer primary key autoincrement, url varchar(1024), isDefault INTEGER);");
+
+ ContentValues values = new ContentValues();
+ values.put("url","https://framapic.org");
+ values.put("isDefault",true);
+ db.insert("servers",null,values);
+ values.clear();
+ values.put("url","https://lut.im");
+ values.put("isDefault",false);
+ db.insert("servers", null, values);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ //nothing to do right now
+ }
+
+ public List
getHistory() {
+ List
history = new ArrayList
();
+ String orderBy = "date ASC";
+ Cursor cursor = getReadableDatabase().query("history", null, null, null, null, null, orderBy);
+ while(cursor.moveToNext())
+ {
+ int col = 0;
+ long id = cursor.getLong(col++);
+ String url = cursor.getString(col++);
+ String shortHash = cursor.getString(col++);
+ String realShortHash = cursor.getString(col++);
+ long timestamp = cursor.getLong(col++);
+ int storageDuration = cursor.getInt(col++);
+ byte[] thumbData = cursor.getBlob(col++);
+
+ Calendar date = Calendar.getInstance();
+ date.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));
+ date.setTimeInMillis(timestamp);
+
+ Img img = new Img(id, url, shortHash, realShortHash, date, storageDuration, thumbData);
+
+ history.add(img);
+ }
+ return history;
+ }
+
+ public void deleteImg(List
deletedList) {
+ for(Img img : deletedList)
+ {
+ String whereClause = "id = ?";
+ String[] whereArgs = new String[1];
+ whereArgs[0] = String.valueOf(img.getId());
+ getWritableDatabase().delete("history", whereClause, whereArgs);
+ }
+ }
+
+ public void addImage(Img img) {
+ ContentValues values = new ContentValues();
+ values.put("url", img.getUrl());
+ values.put("short_hash", img.getShortHash());
+ values.put("real_short_hash", img.getRealShortHash());
+ values.put("date", img.getDate().getTimeInMillis());
+ values.put("storage_duration", img.getStorageDuration());
+ if(img.getThumbData() != null)
+ values.put("thumb",img.getThumbData());
+ getWritableDatabase().insert("history", null, values);
+ }
+
+ public void addServer(String url)
+ {
+ ContentValues values = new ContentValues();
+ values.put("url",url);
+ values.put("isDefault",false);
+ getWritableDatabase().insert("servers", null, values);
+ }
+
+ public List getServers(boolean defaultFirst)
+ {
+ List servers = new ArrayList();
+ Cursor cursor = getReadableDatabase().query("servers", null, null, null, null, null, null);
+ while(cursor.moveToNext())
+ {
+ int col = 0;
+ long id = cursor.getLong(col++);
+ String url = cursor.getString(col++);
+ int defValue = cursor.getInt(col++);
+ boolean isDefault = false;
+ if(defValue == 1)
+ isDefault = true;
+ Server server = new Server(id, url, isDefault);
+ if(defaultFirst && isDefault)
+ {
+ servers.add(0,server);
+ }
+ else
+ {
+ servers.add(server);
+ }
+
+ }
+ return servers;
+ }
+
+ public void deleteServer(long idServer)
+ {
+ String whereClause ="id = ?";
+ String[] whereArgs = new String[1];
+ whereArgs[0] = String.valueOf(idServer);
+ getWritableDatabase().delete("servers",whereClause,whereArgs);
+ }
+
+ public void setDefaultServer(long newDefaultId, long oldDefaultId)
+ {
+ String whereClause = "id = ?";
+ String[] whereargs = new String[1];
+ whereargs[0] = String.valueOf(newDefaultId);
+ ContentValues values = new ContentValues();
+ values.put("isDefault",true);
+ getWritableDatabase().update("servers", values, whereClause, whereargs);
+
+ if(oldDefaultId != -1) {
+ values.clear();
+ whereargs[0] = String.valueOf(oldDefaultId);
+ values.put("isDefault", false);
+ getWritableDatabase().update("servers", values, whereClause, whereargs);
+ }
+ }
+}
diff --git a/app/src/main/java/fr/mobdev/gobelim/NetworkManager.java b/app/src/main/java/fr/mobdev/gobelim/NetworkManager.java
new file mode 100644
index 0000000..1bb966c
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/NetworkManager.java
@@ -0,0 +1,215 @@
+package fr.mobdev.gobelim;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Calendar;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
+import android.util.Log;
+
+import fr.mobdev.gobelim.listener.NetworkListener;
+import fr.mobdev.gobelim.objects.Img;
+
+public class NetworkManager {
+
+ private NetworkListener listener;
+ private static NetworkManager instance;
+ private Context context;
+ private static int id;
+
+ private NetworkManager(NetworkListener listener,Context context)
+ {
+ this.listener = listener;
+ this.context = context;
+ }
+
+ public static NetworkManager getInstance(NetworkListener listener, Context context){
+ if (instance == null)
+ instance = new NetworkManager(listener,context);
+ if(listener != instance.getListener())
+ instance.setListener(listener);
+ return instance;
+ }
+
+ private NetworkListener getListener()
+ {
+ return listener;
+ }
+
+ private void setListener(NetworkListener listener)
+ {
+ this.listener = listener;
+ }
+
+ public void upload(final String siteUrl, final int nbDays, final String fileName, final byte[] bytearray)
+ {
+ if(!isConnectedToInternet(context))
+ return;
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ Img img = uploadImage(siteUrl,nbDays, fileName,bytearray);
+ if(img != null)
+ listener.fileUploaded(img);
+ }
+ }).start();
+ }
+
+ public Img uploadImage(String siteUrl, int nbDays, String fileName, byte[] byteArray) {
+ Log.v("Url",siteUrl);
+ //getData
+ URL url = null;
+ Img imgOutput = null;
+ try {
+ url = new URL(siteUrl);
+ } catch (MalformedURLException e1) {
+ e1.printStackTrace();
+ }
+
+ HttpURLConnection conn = null;
+ InputStream stream = null;
+ DataOutputStream request = null;
+ try {
+ if(isConnectedToInternet(context))
+ {
+ String attachmentFileName = fileName;
+ String crlf = "\r\n";
+ String hyphens = "--";
+ String boundary = "------------------------dd8a045fcc22b35c";
+
+ conn = (HttpURLConnection) url.openConnection();
+
+ int responseCode = conn.getResponseCode();
+
+ String location = conn.getHeaderField("Location");
+ if(location != null) {
+ siteUrl = location;
+ url = new URL(location);
+ }
+ conn = (HttpURLConnection) url.openConnection();
+
+ conn.setRequestMethod("POST");
+ conn.setUseCaches(false);
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+
+ conn.setRequestProperty("User-Agent", "Gobelim");
+// conn.setFixedLengthStreamingMode(byteArray.length);
+// conn.setChunkedStreamingMode(0);
+
+ conn.setInstanceFollowRedirects(true);
+ //conn.set
+ conn.setRequestProperty("Expect", "100-continue");
+ conn.setRequestProperty("Accept", "*/*");
+ conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
+
+
+ request = new DataOutputStream(conn.getOutputStream());
+
+ request.writeBytes(hyphens + boundary + crlf);
+ request.writeBytes("Content-Disposition: form-data; name=\"format\"" + crlf);
+ request.writeBytes(crlf);
+ request.writeBytes("json" + crlf);
+
+ request.writeBytes(hyphens + boundary + crlf);
+ request.writeBytes("Content-Disposition: form-data; name=\"delete-day\"" + crlf);
+ request.writeBytes(crlf);
+ request.writeBytes(nbDays + crlf);
+
+ request.writeBytes(hyphens + boundary + crlf);
+ request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + attachmentFileName + "\"" + crlf);
+ request.writeBytes("Content-Type: application/octet-stream" + crlf);
+ request.writeBytes(crlf);
+ request.flush();
+
+ request.write(byteArray);
+
+ request.writeBytes(crlf);
+ request.writeBytes(hyphens + boundary + hyphens + crlf);
+ request.flush();
+
+ stream = conn.getInputStream();
+ }
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ listener.fileUploadError("Network Error");
+ }
+
+ /******************************************************************************/
+ if(stream != null) {
+ InputStreamReader isr = new InputStreamReader(stream);
+ BufferedReader br = new BufferedReader(isr);
+ boolean isReading = true;
+ String data;
+ String jsonStr = "";
+ do {
+ try {
+ data = br.readLine();
+ if (data != null)
+ jsonStr += data;
+ else
+ isReading = false;
+ } catch (IOException e) {
+ e.printStackTrace();
+ isReading = false;
+ }
+ } while (isReading);
+ //parseJSon
+ try {
+ request.close();
+ stream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ System.out.println("after read answer");
+ System.out.println(jsonStr);
+ try {
+ JSONObject rootObject = new JSONObject(jsonStr); // Parse the JSON to a JSONObject
+ JSONObject msg = rootObject.getJSONObject("msg"); // Get the element object
+ if(msg.has("msg")) {
+ String error = msg.getString("msg");
+ listener.fileUploadError(error);
+ return null;
+ }
+ else if(msg.has("short")) {
+ String hashOutput = msg.getString("short");
+ String realHashOutput = msg.getString("real_short");
+ imgOutput = new Img(0, siteUrl, hashOutput, realHashOutput, Calendar.getInstance(), nbDays, null);
+ }
+ } catch (JSONException e) {
+ // JSON Parsing error
+ e.printStackTrace();
+ listener.fileUploadError("JSON Unreadable");
+ }
+ }
+ return imgOutput;
+ }
+
+ private boolean isConnectedToInternet(Context context)
+ {
+ ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
+ if (networkInfo != null)
+ {
+ State networkState = networkInfo.getState();
+ if (networkState.equals(State.CONNECTED))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/mobdev/gobelim/activity/HistoryActivity.java b/app/src/main/java/fr/mobdev/gobelim/activity/HistoryActivity.java
new file mode 100644
index 0000000..105e166
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/activity/HistoryActivity.java
@@ -0,0 +1,120 @@
+package fr.mobdev.gobelim.activity;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.app.ActionBarActivity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import fr.mobdev.gobelim.Database;
+import fr.mobdev.gobelim.objects.Img;
+import fr.mobdev.gobelim.R;
+
+
+public class HistoryActivity extends ActionBarActivity {
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.history);
+ ListView historyList = (ListView) findViewById(R.id.history_list);
+ final List
images = Database.getInstance(getApplicationContext()).getHistory();
+ HistoryAdapter adapter = new HistoryAdapter(this,R.layout.history_item,R.id.url_history_item,images);
+ historyList.setAdapter(adapter);
+ historyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Intent linkIntent = new Intent(HistoryActivity.this,LinkActivity.class);
+ if(position < images.size()) {
+ Img image = images.get(position);
+ linkIntent.putExtra("URL", image.getUrl());
+ linkIntent.putExtra("short", image.getShortHash());
+ startActivity(linkIntent);
+ }
+ }
+ });
+ }
+
+ private class HistoryAdapter extends ArrayAdapter
+ {
+
+ private List
images;
+ private LayoutInflater mInflater;
+ int resource;
+
+ public HistoryAdapter(Context context, int resource, int textViewResourceId, List
objects) {
+ super(context, resource, textViewResourceId, objects);
+ images = new ArrayList(objects);
+ this.resource = resource;
+ mInflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent)
+ {
+ Img image = images.get(position);
+ if (convertView == null) {
+ convertView = mInflater.inflate(resource, parent, false);
+ }
+
+ TextView urlView = (TextView) convertView.findViewById(R.id.url_history_item);
+ String url = image.getUrl();
+ if(!url.endsWith("/"))
+ url+="/";
+ url+=image.getShortHash();
+ urlView.setText(url);
+
+ //display date
+ TextView dateView = (TextView) convertView.findViewById(R.id.date);
+ Calendar date = image.getDate();
+ DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
+ df.setTimeZone(TimeZone.getDefault());
+ String dateString = df.format(date.getTime());
+ dateView.setText(dateString);
+
+ //display durationLastDay
+ TextView durationView = (TextView) convertView.findViewById(R.id.duration);
+ int storageDuration = image.getStorageDuration();
+ if(storageDuration == 0) {
+ durationView.setText(getString(R.string.no_duration));
+ }
+ else {
+ Calendar today = Calendar.getInstance();
+ long millis = today.getTimeInMillis() - date.getTimeInMillis();
+ long days = millis / (24*60*60*1000);
+ if(storageDuration - days < 0) {
+ durationView.setText(getString(R.string.duration_ended));
+ }
+ else {
+ if(storageDuration - days == 1)
+ durationView.setText(storageDuration - days +" "+ getString(R.string.day));
+ else
+ durationView.setText(storageDuration - days +" "+ getString(R.string.days));
+ }
+ }
+
+
+ ImageView thumb = (ImageView) convertView.findViewById(R.id.thumbnail);
+ if(image.getThumb() != null)
+ thumb.setImageBitmap(image.getThumb());
+
+ return convertView;
+ }
+ }
+}
+
diff --git a/app/src/main/java/fr/mobdev/gobelim/activity/LinkActivity.java b/app/src/main/java/fr/mobdev/gobelim/activity/LinkActivity.java
new file mode 100644
index 0000000..48a7e4f
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/activity/LinkActivity.java
@@ -0,0 +1,60 @@
+package fr.mobdev.gobelim.activity;
+
+import android.content.Intent;
+import android.support.v7.app.ActionBarActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+import android.content.ClipboardManager;
+import android.widget.Toast;
+
+import fr.mobdev.gobelim.R;
+
+
+public class LinkActivity extends ActionBarActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.link);
+
+ Intent receiveIntent = getIntent();
+ String url = receiveIntent.getStringExtra("URL");
+ String shortHash = receiveIntent.getStringExtra("short");
+
+ if(!url.endsWith("/"))
+ url = url.concat("/");
+ url = url.concat(shortHash);
+
+ final String sharedUrl = url;
+
+ ImageButton shareButton = (ImageButton) findViewById(R.id.share_button);
+ shareButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent sendIntent = new Intent();
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_TEXT, sharedUrl);
+ sendIntent.setType("text/plain");
+ startActivity(sendIntent);
+ }
+ });
+
+ ImageButton copyClipboardButton = (ImageButton) findViewById(R.id.copy_clipboard_button);
+ copyClipboardButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ android.content.ClipData clip = android.content.ClipData.newPlainText("Copied URL", sharedUrl);
+ clipboard.setPrimaryClip(clip);
+ Toast.makeText(LinkActivity.this,getString(R.string.copy_to_clipboard),Toast.LENGTH_SHORT).show();
+ }
+ });
+
+ TextView link = (TextView) findViewById(R.id.link);
+ link.setText(sharedUrl);
+ }
+
+}
diff --git a/app/src/main/java/fr/mobdev/gobelim/activity/MainActivity.java b/app/src/main/java/fr/mobdev/gobelim/activity/MainActivity.java
new file mode 100644
index 0000000..c827a6c
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/activity/MainActivity.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2015 Anthony Chomienne, anthony@mob-dev.fr
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package fr.mobdev.gobelim.activity;
+
+import android.app.ProgressDialog;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.support.v7.app.ActionBarActivity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.Toast;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.mobdev.gobelim.Database;
+import fr.mobdev.gobelim.listener.NetworkListener;
+import fr.mobdev.gobelim.NetworkManager;
+import fr.mobdev.gobelim.objects.Img;
+import fr.mobdev.gobelim.objects.Server;
+import fr.mobdev.gobelim.R;
+
+public class MainActivity extends ActionBarActivity {
+
+ private NetworkListener listener;
+ private Uri imageUri;
+ private String fileName;
+ private List urls;
+ private List deletedDays;
+ private ProgressDialog progressDialog;
+
+ private static final int NEVER = 0;
+ private static final int ONE = 1;
+ private static final int SEVEN = 7;
+ private static final int THIRTY = 30;
+ private static final int YEAR = 365;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ imageUri = null;
+ urls = new ArrayList<>();
+ deletedDays = new ArrayList<>();
+ deletedDays.add(NEVER);
+ deletedDays.add(ONE);
+ deletedDays.add(SEVEN);
+ deletedDays.add(THIRTY);
+ deletedDays.add(YEAR);
+
+ updateServerList();
+ if(savedInstanceState != null) {
+ int selectedServer = savedInstanceState.getInt("selectedServer");
+ imageUri = savedInstanceState.getParcelable("imageURI");
+ if (selectedServer < urls.size()) {
+ Spinner servers = (Spinner) findViewById(R.id.servers_spinner);
+ servers.setSelection(selectedServer);
+ }
+ }
+
+ listener = new NetworkListener() {
+ @Override
+ public void fileUploaded(final Img image) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ //add uploaded img to history
+ Database.getInstance(getApplicationContext()).addImage(image);
+ //dismiss progressDialog
+ progressDialog.dismiss();
+ //launch LinkActivity
+ Intent linkIntent = new Intent(MainActivity.this,LinkActivity.class);
+ linkIntent.putExtra("URL", image.getUrl());
+ linkIntent.putExtra("short",image.getShortHash());
+ startActivity(linkIntent);
+ }
+ });
+ }
+
+ @Override
+ public void fileUploadError(final String error) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ //display toast error
+ Toast.makeText(MainActivity.this, error, Toast.LENGTH_SHORT).show();
+ progressDialog.dismiss();
+ }
+ });
+ }
+ };
+
+ Button uploadBt = (Button) findViewById(R.id.upload_button);
+ uploadBt.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ uploadImage();
+ }
+ });
+
+ //prepare for asking user the image he want share
+ Button selectBt = (Button) findViewById(R.id.select_button);
+ selectBt.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ requestFile();
+ }
+ });
+
+ //have we receive image from share or do you need to ask it to the user
+ Intent receiveIntent = getIntent();
+ if(receiveIntent == null || receiveIntent.getType() == null || !receiveIntent.getType().contains("image/")) {
+ uploadBt.setVisibility(View.GONE);
+ }
+ else {
+ selectBt.setVisibility(View.GONE);
+ imageUri = receiveIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+ displayImage();
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ //update server list to manage change in ServerActivity
+ updateServerList();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle savedInstanceState) {
+ savedInstanceState.putParcelable("imageURI", imageUri);
+ Spinner selectedServer = (Spinner) findViewById(R.id.servers_spinner);
+ int pos = selectedServer.getSelectedItemPosition();
+ savedInstanceState.putInt("selectedServer", pos);
+ super.onSaveInstanceState(savedInstanceState);
+ }
+
+ private void updateServerList() {
+ Spinner serversSpinner = (Spinner) findViewById(R.id.servers_spinner);
+ String selectedServer = (String) serversSpinner.getSelectedItem();
+
+ List servers = Database.getInstance(getApplicationContext()).getServers(true);
+ urls.clear();
+ int pos = 0;
+ for(Server server : servers) {
+ if(server.getUrl().equals(selectedServer)) {
+ pos = urls.size();
+ }
+ urls.add(server.getUrl());
+ }
+
+ ArrayAdapter adapter = new ArrayAdapter<>(this,android.R.layout.simple_dropdown_item_1line,urls);
+ serversSpinner.setAdapter(adapter);
+
+ serversSpinner.setSelection(pos);
+ }
+
+ private void displayImage() {
+ FileInputStream fileStream = null;
+ File file;
+ if(imageUri != null) {
+ ContentResolver contentResolver = getContentResolver();
+ Cursor cursor = contentResolver.query(imageUri, null, null, null, null);
+ cursor.moveToFirst();
+ String filePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
+ cursor.close();
+ file = new File(filePath);
+ fileName = file.getName();
+ try {
+ fileStream = new FileInputStream(file);
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ if(fileStream != null) {
+ try {
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ int readed = 0;
+ byte[] buffer = new byte[1024];
+ while(readed != -1) {
+ try {
+ readed = fileStream.read(buffer);
+ if(readed != -1)
+ outStream.write(buffer,0,readed);
+ } catch (IOException e) {
+ e.printStackTrace();
+ readed = -1;
+ }
+ }
+ byte[] bytearray = outStream.toByteArray();
+
+
+ Bitmap bt = BitmapFactory.decodeByteArray(bytearray,0,bytearray.length);
+ ImageView view = (ImageView) findViewById(R.id.thumbnail_main);
+ view.setImageBitmap(bt);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void uploadImage() {
+ //what server we use
+ Spinner urlSpinner = (Spinner)findViewById(R.id.servers_spinner);
+ int pos = urlSpinner.getSelectedItemPosition();
+ if(urls.size() < pos) {
+ Toast.makeText(this,getString(R.string.server_list_error),Toast.LENGTH_LONG).show();
+ return;
+ }
+ String url = urls.get(pos);
+
+ Spinner deleteSpinner = (Spinner)findViewById(R.id.delete_day_spinner);
+ pos = deleteSpinner.getSelectedItemPosition();
+ int delete = deletedDays.get(pos);
+
+ byte[] bytearray = null;
+ FileInputStream fileStream = null;
+ if(imageUri != null) {
+ ContentResolver contentResolver = getContentResolver();
+ Cursor cursor = contentResolver.query(imageUri, null, null, null, null);
+ cursor.moveToFirst();
+ String filePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
+ cursor.close();
+ File file = new File(filePath);
+ fileName = file.getName();
+ try {
+ fileStream = new FileInputStream(file);
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ if(fileStream != null) {
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ int readed = 0;
+ byte[] buffer = new byte[1024];
+ while(readed != -1) {
+ try {
+ readed = fileStream.read(buffer);
+ if(readed != -1)
+ outStream.write(buffer,0,readed);
+ } catch (IOException e) {
+ e.printStackTrace();
+ readed = -1;
+ }
+ }
+ bytearray = outStream.toByteArray();
+ }
+ if(bytearray != null && bytearray.length > 0) {
+ progressDialog = new ProgressDialog(MainActivity.this);
+ progressDialog.setMessage(getString(R.string.upload_progress));
+ progressDialog.setCancelable(false);
+ progressDialog.show();
+ NetworkManager.getInstance(listener, getApplicationContext()).upload(url, delete, fileName, bytearray);
+ }
+ else {
+ listener.fileUploadError("Empty file or Unable to read the file");
+ }
+ }
+
+ protected void requestFile() {
+ Intent requestFileIntent = new Intent(Intent.ACTION_PICK);
+ requestFileIntent.setType("image/*");
+ startActivityForResult(requestFileIntent, 0);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode,Intent returnIntent) {
+ if(resultCode == RESULT_OK){
+ imageUri = returnIntent.getData();
+ Button uploadBt = (Button) findViewById(R.id.upload_button);
+ uploadBt.setVisibility(View.VISIBLE);
+
+ Button selectButton = (Button) findViewById(R.id.select_button);
+ selectButton.setVisibility(View.GONE);
+ displayImage();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+
+ if (id == R.id.action_manage_server) {
+ Intent serverIntent = new Intent(this,ServersActivity.class);
+ startActivity(serverIntent);
+ return true;
+ }
+ else if (id == R.id.action_show_history){
+ Intent historyIntent = new Intent(this,HistoryActivity.class);
+ startActivity(historyIntent);
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/app/src/main/java/fr/mobdev/gobelim/activity/ServersActivity.java b/app/src/main/java/fr/mobdev/gobelim/activity/ServersActivity.java
new file mode 100644
index 0000000..0b8972a
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/activity/ServersActivity.java
@@ -0,0 +1,175 @@
+package fr.mobdev.gobelim.activity;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Typeface;
+import android.provider.ContactsContract;
+import android.support.v7.app.ActionBarActivity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.mobdev.gobelim.Database;
+import fr.mobdev.gobelim.dialog.ServerDialog;
+import fr.mobdev.gobelim.listener.ServerListener;
+import fr.mobdev.gobelim.objects.Server;
+import fr.mobdev.gobelim.R;
+
+
+public class ServersActivity extends ActionBarActivity {
+
+ private List dbServers;
+ private View.OnClickListener listener;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.servers);
+ ListView serverList = (ListView) findViewById(R.id.servers_list);
+ serverList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
+ //find oldDefault
+ Server oldDefaultServer = null;
+ for(Server server : dbServers)
+ {
+ if(server.isDefaultServer())
+ {
+ oldDefaultServer = server;
+ break;
+ }
+ }
+ Server newDefaultServer = dbServers.get(position);
+ if(oldDefaultServer == null) {
+ Database.getInstance(getApplicationContext()).setDefaultServer(newDefaultServer.getId(),-1);
+ }
+ else {
+ Database.getInstance(getApplicationContext()).setDefaultServer(newDefaultServer.getId(), oldDefaultServer.getId());
+ }
+ updateServers();
+ return true;
+ }
+ });
+
+ listener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ ListView serverList = (ListView) findViewById(R.id.servers_list);
+ Integer pos = (Integer)v.getTag();
+ if(pos == null)
+ return;
+ final Server server = dbServers.get(pos.intValue());
+ //ask delete
+ AlertDialog.Builder builder = new AlertDialog.Builder(ServersActivity.this);
+ builder.setMessage(getString(R.string.delete_server_message)+" "+server.getUrl())
+ .setCancelable(false)
+ .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dbServers.remove(server);
+ Database.getInstance(getApplicationContext()).deleteServer(server.getId());
+ updateServers();
+ }
+ })
+ .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+ };
+ updateServers();
+ }
+
+ private void updateServers()
+ {
+ dbServers = Database.getInstance(getApplicationContext()).getServers(false);
+
+ ServerAdapter adapter = new ServerAdapter(this,R.layout.server_item,R.id.server_name,dbServers,listener);
+
+ ListView serverList = (ListView) findViewById(R.id.servers_list);
+ serverList.setAdapter(adapter);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_servers, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+
+ if (id == R.id.action_add_server) {
+
+ ServerDialog serverDialog = new ServerDialog();
+ ServerListener serverListener = new ServerListener() {
+ @Override
+ public void updateServerList() {
+ updateServers();
+ }
+ };
+ serverDialog.setServerListener(serverListener);
+ serverDialog.show(getSupportFragmentManager(),"Server Dialog");
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private class ServerAdapter extends ArrayAdapter
+ {
+
+ private List servers;
+ private LayoutInflater mInflater;
+ private View.OnClickListener listener;
+ int resource;
+
+ public ServerAdapter(Context context, int resource, int textViewResourceId, List objects, View.OnClickListener listener) {
+ super(context, resource, textViewResourceId, objects);
+ servers = new ArrayList(objects);
+ this.listener = listener;
+ this.resource = resource;
+ mInflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent)
+ {
+ Server server = servers.get(position);
+ if (convertView == null) {
+ convertView = mInflater.inflate(resource, parent, false);
+ }
+
+ TextView view = (TextView) convertView.findViewById(R.id.server_name);
+ if(server.isDefaultServer()) {
+ Typeface typeface = view.getTypeface();
+ Typeface newTypeface = Typeface.create(typeface,Typeface.BOLD);
+ view.setTypeface(newTypeface);
+ }
+ view.setText(server.getUrl());
+
+ ImageView delete = (ImageView) convertView.findViewById(R.id.server_delete);
+ delete.setOnClickListener(listener);
+ delete.setTag(Integer.valueOf(position));
+
+ return convertView;
+ }
+ }
+}
diff --git a/app/src/main/java/fr/mobdev/gobelim/dialog/ServerDialog.java b/app/src/main/java/fr/mobdev/gobelim/dialog/ServerDialog.java
new file mode 100644
index 0000000..b829ac2
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/dialog/ServerDialog.java
@@ -0,0 +1,67 @@
+package fr.mobdev.gobelim.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Spinner;
+
+import fr.mobdev.gobelim.Database;
+import fr.mobdev.gobelim.listener.ServerListener;
+import fr.mobdev.gobelim.R;
+
+
+public class ServerDialog extends DialogFragment {
+
+ private static final int HTTP_POSITION = 0;
+ private static final int HTTPS_POSITION = 1;
+
+ private ServerListener listener;
+
+ public void setServerListener(ServerListener listener)
+ {
+ this.listener = listener;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ final View view = inflater.inflate(R.layout.server_dialog, null);
+
+ EditText urlText = (EditText) view.findViewById(R.id.url_text);
+ //mask for url?
+
+ builder.setView(view)
+ .setTitle(R.string.server_title)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String url = "http";
+ Spinner httpSpinner = (Spinner) view.findViewById(R.id.http_spinner);
+ if(httpSpinner.getSelectedItemPosition() == HTTPS_POSITION)
+ url += "s";
+ url +="://";
+ EditText urlText = (EditText) view.findViewById(R.id.url_text);
+ if(urlText.getText().length() > 0)
+ url += urlText.getText();
+ Database.getInstance(getActivity().getApplicationContext()).addServer(url);
+ listener.updateServerList();
+ dismiss();
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss();
+ }
+ });
+
+ return builder.create();
+ }
+}
diff --git a/app/src/main/java/fr/mobdev/gobelim/listener/NetworkListener.java b/app/src/main/java/fr/mobdev/gobelim/listener/NetworkListener.java
new file mode 100644
index 0000000..9625773
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/listener/NetworkListener.java
@@ -0,0 +1,11 @@
+package fr.mobdev.gobelim.listener;
+
+import java.util.EventListener;
+import java.util.List;
+
+import fr.mobdev.gobelim.objects.Img;
+
+public interface NetworkListener extends EventListener{
+ void fileUploaded(Img image);
+ void fileUploadError(String error);
+}
diff --git a/app/src/main/java/fr/mobdev/gobelim/listener/ServerListener.java b/app/src/main/java/fr/mobdev/gobelim/listener/ServerListener.java
new file mode 100644
index 0000000..16a53d3
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/listener/ServerListener.java
@@ -0,0 +1,7 @@
+package fr.mobdev.gobelim.listener;
+
+import java.util.EventListener;
+
+public interface ServerListener extends EventListener {
+ public void updateServerList();
+}
diff --git a/app/src/main/java/fr/mobdev/gobelim/objects/Img.java b/app/src/main/java/fr/mobdev/gobelim/objects/Img.java
new file mode 100644
index 0000000..c90f182
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/objects/Img.java
@@ -0,0 +1,77 @@
+package fr.mobdev.gobelim.objects;
+
+import android.graphics.Bitmap;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Calendar;
+
+public class Img {
+
+ private Long id;
+ private String url;
+ private Calendar date;
+ private int storageDuration;
+ private Bitmap image;
+ private String shortHash;
+ private String realShortHash;
+
+ public Img(long id, String url, String shortHash, String realShortHash, Calendar date, int storageDuration, byte[] thumbData) {
+ this.url = url;
+ this.shortHash = shortHash;
+ this.id = id;
+ this.realShortHash = realShortHash;
+ this.date = date;
+ this.storageDuration = storageDuration;
+ }
+
+ public Long getId()
+ {
+ return id;
+ }
+
+ public String getUrl()
+ {
+ return url;
+ }
+
+ public Calendar getDate()
+ {
+ return date;
+ }
+
+ public Bitmap getThumb()
+ {
+ return image;
+ }
+
+ public String getShortHash()
+ {
+ return shortHash;
+ }
+
+ public String getRealShortHash()
+ {
+ return realShortHash;
+ }
+
+ public int getStorageDuration()
+ {
+ return storageDuration;
+ }
+
+ public byte[] getThumbData()
+ {
+ if(image != null) {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ image.compress(Bitmap.CompressFormat.PNG, 100, stream);
+ byte[] byteArray = stream.toByteArray();
+
+ return byteArray;
+ }
+ else {
+ return null;
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/fr/mobdev/gobelim/objects/Server.java b/app/src/main/java/fr/mobdev/gobelim/objects/Server.java
new file mode 100644
index 0000000..5871cca
--- /dev/null
+++ b/app/src/main/java/fr/mobdev/gobelim/objects/Server.java
@@ -0,0 +1,31 @@
+package fr.mobdev.gobelim.objects;
+
+public class Server {
+
+ private long id;
+ private String url;
+ private boolean defaultServer;
+
+ public Server(long id, String url, boolean defaultServer)
+ {
+ this.id = id;
+ this.url = url;
+ this.defaultServer = defaultServer;
+ }
+
+ public String getUrl()
+ {
+ return url;
+ }
+
+ public long getId()
+ {
+ return id;
+ }
+
+ public boolean isDefaultServer()
+ {
+ return defaultServer;
+ }
+
+}
diff --git a/app/src/main/res/layout/history.xml b/app/src/main/res/layout/history.xml
new file mode 100644
index 0000000..ee7ec74
--- /dev/null
+++ b/app/src/main/res/layout/history.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/history_item.xml b/app/src/main/res/layout/history_item.xml
new file mode 100644
index 0000000..c259d20
--- /dev/null
+++ b/app/src/main/res/layout/history_item.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/link.xml b/app/src/main/res/layout/link.xml
new file mode 100644
index 0000000..0355f64
--- /dev/null
+++ b/app/src/main/res/layout/link.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/main.xml b/app/src/main/res/layout/main.xml
new file mode 100644
index 0000000..0104f87
--- /dev/null
+++ b/app/src/main/res/layout/main.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/server_dialog.xml b/app/src/main/res/layout/server_dialog.xml
new file mode 100644
index 0000000..6315f19
--- /dev/null
+++ b/app/src/main/res/layout/server_dialog.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/server_item.xml b/app/src/main/res/layout/server_item.xml
new file mode 100644
index 0000000..0d50494
--- /dev/null
+++ b/app/src/main/res/layout/server_item.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/servers.xml b/app/src/main/res/layout/servers.xml
new file mode 100644
index 0000000..ff11ae2
--- /dev/null
+++ b/app/src/main/res/layout/servers.xml
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..d3ec188
--- /dev/null
+++ b/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,14 @@
+
diff --git a/app/src/main/res/menu/menu_servers.xml b/app/src/main/res/menu/menu_servers.xml
new file mode 100644
index 0000000..70bf2c0
--- /dev/null
+++ b/app/src/main/res/menu/menu_servers.xml
@@ -0,0 +1,8 @@
+
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..47c8224
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a35784a
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,36 @@
+
+ Gobelim
+
+ Paramètres
+ Partager
+ Historique
+ Partager le lien
+ Liste des serveurs
+ Envoyer
+ Selectionner une Image
+ durée de\nConservation
+ Lien copié dans le presse-papier
+ Ajouter un serveur
+ Adresse du site
+ Ajouter un serveur
+ Gérer les serveurs
+ Voir l\'historique
+ Supprimer le server
+ Envoi en cours
+
+ Supprimée
+ Jours restants
+ Jour restant
+ Vous n\t fetch'avez aucun serveur configuré, merci d\'en ajouter un
+
+ - Pas de limitation
+ - 24 Heures
+ - 7 Jours
+ - 30 Jours
+ - 1 an
+
+
+ - http://
+ - https://
+
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..9405f3f
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.2.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'