diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml new file mode 100644 index 0000000..800ca3d --- /dev/null +++ b/.idea/assetWizardSettings.xml @@ -0,0 +1,153 @@ + + + + + + \ No newline at end of file diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser index 38396b4..bf8df3d 100644 Binary files a/.idea/caches/gradle_models.ser and b/.idea/caches/gradle_models.ser differ diff --git a/app/build.gradle b/app/build.gradle index 2b2bc6c..06f1423 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -40,4 +40,5 @@ dependencies { implementation 'com.android.support:cardview-v7:28.0.0' implementation 'com.github.danielnilsson9:color-picker-view:1.4.0@aar' implementation 'com.android.support:recyclerview-v7:28.0.0' + implementation 'com.android.support:support-v4:28.0.0' } diff --git a/app/src/main/java/at/smartshopper/smartshopper/activitys/Dash.java b/app/src/main/java/at/smartshopper/smartshopper/activitys/Dash.java index b9804f7..c479c45 100644 --- a/app/src/main/java/at/smartshopper/smartshopper/activitys/Dash.java +++ b/app/src/main/java/at/smartshopper/smartshopper/activitys/Dash.java @@ -1,5 +1,8 @@ package at.smartshopper.smartshopper.activitys; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.net.Uri; @@ -7,10 +10,13 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.design.widget.TabLayout; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; @@ -44,12 +50,12 @@ import at.smartshopper.smartshopper.shoppinglist.Shoppinglist; import at.smartshopper.smartshopper.shoppinglist.ShoppinglistAdapter; -public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnItemClicked, ShoppinglistAdapter.OnChangeItemClick { +public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnItemClicked, ShoppinglistAdapter.OnChangeItemClick, ShoppinglistAdapter.OnShareClick { private Database db = new Database(); - private SwipeRefreshLayout ownswiperefresh; + private SwipeRefreshLayout ownswiperefresh, sharedswiperefresh; private FloatingActionButton addShoppinglistFab; - private PopupWindow popupWindowAdd; + private PopupWindow popupWindowAdd, popupShare, popupAddShare; private String color; private Button colorBtn; @@ -116,12 +122,30 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte try { try { showOwnShoppingList(uid); + showSharedShoppingList(uid); } catch (SQLException e) { e.printStackTrace(); } } catch (JSONException e) { e.printStackTrace(); } + + sharedswiperefresh = (SwipeRefreshLayout) findViewById(R.id.sharedSwipe); + + sharedswiperefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + try { + showSharedShoppingList(uid); + sharedswiperefresh.setRefreshing(false); + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + } + }); ownswiperefresh = (SwipeRefreshLayout) findViewById(R.id.ownSwipe); ownswiperefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @@ -187,9 +211,9 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte if (fromDB) { Shoppinglist dbShoppinglist = db.getShoppinglist(sl_id); String colorstring; - if(dbShoppinglist.getcolor().contains("#")){ + if (dbShoppinglist.getcolor().contains("#")) { colorstring = dbShoppinglist.getcolor(); - }else{ + } else { colorstring = "#" + dbShoppinglist.getcolor(); } this.color = colorstring; @@ -205,7 +229,7 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte @Override public void onClick(View v) { - if(fromDB){ + if (fromDB) { try { db.editShoppinglist(sl_idString, name.getText().toString(), description.getText().toString(), color); color = "ffffff"; @@ -216,7 +240,7 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte } catch (JSONException e) { e.printStackTrace(); } - }else { + } else { try { db.addShoppinglist(name.getText().toString(), description.getText().toString(), username, color); color = "ffffff"; @@ -259,6 +283,7 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte popupWindowAdd.setOutsideTouchable(false); popupWindowAdd.setFocusable(true); + popupWindowAdd.setAnimationStyle(R.style.popup_window_animation_phone); popupWindowAdd.showAtLocation(v, Gravity.CENTER, 0, 0); @@ -301,6 +326,24 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte } + /** + * Macht eine Datenbankverbindung und holt alle Shoppinglists die mit dem User geteilt werden, diese werden auf dem recycled view angezeigt + * + * @param uid Die UserId damit von diesem user die shoppinglisten angezeigt werden + */ + private void showSharedShoppingList(String uid) throws JSONException, SQLException { + RecyclerView sharedRecycler = (RecyclerView) findViewById(R.id.sharedrecycler); + sharedRecycler.setHasFixedSize(true); + sharedRecycler.setLayoutManager(new LinearLayoutManager(this)); + List ownListsList = db.getSharedShoppinglists(uid); + ShoppinglistAdapter shpAdapter = new ShoppinglistAdapter(Dash.this, ownListsList); + shpAdapter.setOnDelClick(Dash.this); + shpAdapter.setOnChangeClick(Dash.this); + shpAdapter.setOnShareClick(Dash.this); + sharedRecycler.setAdapter(shpAdapter); + + } + /** * Macht eine Datenbankverbindung und holt alle Shoppinglists die dem User gehören, diese werden auf dem recycled view angezeigt * @@ -314,6 +357,7 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte ShoppinglistAdapter shpAdapter = new ShoppinglistAdapter(Dash.this, ownListsList); shpAdapter.setOnDelClick(Dash.this); shpAdapter.setOnChangeClick(Dash.this); + shpAdapter.setOnShareClick(Dash.this); ownRecycleView.setAdapter(shpAdapter); } @@ -371,6 +415,9 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte logout(); return true; + case R.id.addInvite: + popupaddInvite(); + default: // If we got here, the user's action was not recognized. // Invoke the superclass to handle it. @@ -379,6 +426,82 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte } } + /** + * Öffnet ein popup in dem ein invite link eingegeben werden kann. Diese Shoppingliste wird dann hinzugefügt + */ + private void popupaddInvite() { + final LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); + View popupContentView = inflater.inflate(R.layout.add_share_link, null); + + final TextView linkEingabe = (TextView) popupContentView.findViewById(R.id.addShareLinkInput); + + ImageButton exitButton = (ImageButton) popupContentView.findViewById(R.id.addShareExit); + Picasso.get().load(R.drawable.close).into(exitButton); + exitButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + popupAddShare.dismiss(); + } + }); + + Button finish = (Button) popupContentView.findViewById(R.id.shareAddFinish); + finish.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String eingabeLink = linkEingabe.getText().toString(); + + String delString = null; + if (eingabeLink.contains("https://")) { + delString = "https://www.smartshopper.cf/invite/"; + } else if (eingabeLink.contains("http://")) { + delString = "http://www.smartshopper.cf/invite/"; + } else if (eingabeLink.contains("www.smartshopper.cf/invite/")) { + delString = "www.smartshopper.cf/invite/"; + } else if (!eingabeLink.contains("www.smartshopper.cf/invite/")) { + delString = ""; + } + String invite = eingabeLink.replace(delString, ""); + + try { + db.addInviteLink(invite, FirebaseAuth.getInstance().getCurrentUser().getUid()); + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + popupAddShare.dismiss(); + + + try { + TabHost tabhost = (TabHost) findViewById(R.id.tabHost1); + tabhost.setCurrentTab(1); + sharedswiperefresh.setRefreshing(true); + showSharedShoppingList(FirebaseAuth.getInstance().getCurrentUser().getUid()); + sharedswiperefresh.setRefreshing(false); + } catch (JSONException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + }); + + popupAddShare = new PopupWindow(popupContentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + popupAddShare.setOutsideTouchable(false); + popupAddShare.setFocusable(true); + // Set an elevation value for popup window + // Call requires API level 21 + if (Build.VERSION.SDK_INT >= 21) { + popupAddShare.setElevation(5.0f); + } + popupAddShare.setAnimationStyle(R.style.popup_window_animation_phone); + + + popupAddShare.showAtLocation(getWindow().getDecorView().findViewById(android.R.id.content), Gravity.CENTER, 0, 0); + popupAddShare.update(); + } + //Für Double Back press to exit private boolean doubleBackToExitPressedOnce = false; @@ -437,4 +560,90 @@ public class Dash extends AppCompatActivity implements ShoppinglistAdapter.OnIte e.printStackTrace(); } } + + @Override + public void onShareClick(String sl_id, View v) { + Log.d("ShareClick test", "Workt sl_id: " + sl_id); + String link = null; + try { + if (db.isShared(sl_id)) { + link = db.getInviteLink(sl_id); + } else { + + link = db.createInviteLink(sl_id); + } + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + final LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); + View popupContentView = inflater.inflate(R.layout.add_share, null); + + final TextView linkausgabe = (TextView) popupContentView.findViewById(R.id.shareLink); + linkausgabe.setText("www.smartshopper.cf/invite/" + link); + + ImageButton exitButton = (ImageButton) popupContentView.findViewById(R.id.shareExit); + Picasso.get().load(R.drawable.close).into(exitButton); + exitButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + popupShare.dismiss(); + } + }); + + Button copyButton = (Button) popupContentView.findViewById(R.id.shareCopy); + copyButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("SmartShopper", linkausgabe.getText().toString()); + clipboard.setPrimaryClip(clip); + popupShare.dismiss(); + } + }); + + Button delShare = (Button) popupContentView.findViewById(R.id.delShare); + + final String finalLink = link; + delShare.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + try { + db.deleteInvite(finalLink); + + + TabHost tabhost = (TabHost) findViewById(R.id.tabHost1); + tabhost.setCurrentTab(1); + sharedswiperefresh.setRefreshing(true); + + showSharedShoppingList(FirebaseAuth.getInstance().getCurrentUser().getUid()); + sharedswiperefresh.setRefreshing(false); + popupShare.dismiss(); + } catch (SQLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + + } + }); + + popupShare = new PopupWindow(popupContentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + popupShare.setOutsideTouchable(false); + popupShare.setFocusable(true); + // Set an elevation value for popup window + // Call requires API level 21 + if (Build.VERSION.SDK_INT >= 21) { + popupShare.setElevation(5.0f); + } + popupShare.setAnimationStyle(R.style.popup_window_animation_phone); + + + popupShare.showAtLocation(v, Gravity.CENTER, 0, 0); + popupShare.update(); + } } diff --git a/app/src/main/java/at/smartshopper/smartshopper/db/Database.java b/app/src/main/java/at/smartshopper/smartshopper/db/Database.java index e74a97b..8eff423 100644 --- a/app/src/main/java/at/smartshopper/smartshopper/db/Database.java +++ b/app/src/main/java/at/smartshopper/smartshopper/db/Database.java @@ -35,7 +35,6 @@ public class Database { public Database() { } - /** * Verbindet Sich mit der Datenbank. Auf der Konsole wird "Database connected!" angezeigt, bei erfolgreicher verbindung * @@ -50,10 +49,125 @@ public class Database { System.out.println("Database connected!"); } + /** + * Entfernt einen invitelink anhand des invitelinks + * @param invitelink Löscht den invitelink aus der ganzen db + * @throws SQLException + * @throws JSONException + */ + public void deleteInvite(String invitelink) throws SQLException, JSONException { + String sl_id = getSlIdFromInvite(invitelink); + sqlUpdate("DELETE FROM \"Shoppinglist_member\" WHERE sl_id = ?", sl_id); + sqlUpdate("Update \"Shoppinglist\" set invitelink=null where sl_id=?", sl_id); + } + + /** + * Gibt den Invite link einer Shoppingliste zurück, wenn keiner vorhanden ist --> null + * @param sl_id Die shoppinglist von der der invitelimnk gefragt ist + * @return Der invite link + * @throws SQLException + * @throws JSONException + */ + public String getInviteLink(String sl_id) throws SQLException, JSONException{ + connectDatabase(); + String SQL = "Select invitelink from \"Shoppinglist\" WHERE sl_id = ?"; + + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, sl_id); + ResultSet rs = pstmt.executeQuery(); + + rs.next(); + String returnLink = rs.getString(1); + + + return returnLink; + } + + /** + * Sucht anhand des invitelinks eine Shoppingliste und gibt dessen sl_id zurück + * @param invitelink Der invitelink nach dem gesucht werden soll + * @return Die sl_id die dem invitelink zugeordnet ist + * @throws SQLException + * @throws JSONException + */ + private String getSlIdFromInvite(String invitelink) throws SQLException, JSONException{ + connectDatabase(); + String SQL = "Select sl_id from \"Shoppinglist\" WHERE invitelink = ?"; + + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, invitelink); + ResultSet rs = pstmt.executeQuery(); + + rs.next(); + String returnSl_id = rs.getString(1); + + + return returnSl_id; + } + + + /** + * Fügt einen invite link zu den shoppinglisten hinzu + * @param invitelink Der invite link der hinzugefügt werden soll + * @param uid Der user zu dem der invitelink hinzugefügt werden soll + * @throws SQLException + * @throws JSONException + */ + public void addInviteLink(String invitelink, String uid) throws SQLException, JSONException { + String sl_id = getSlIdFromInvite(invitelink); + if(!sl_id.equals("null")){ + sqlUpdate2Param("INSERT INTO \"Shoppinglist_member\" (username, sl_id) VALUES (?, ?)", uid, sl_id); + } + } + + /** + * Erstellt einen neuen InviteLink + * @param sl_id + * @return Der neue InviteLink + * @throws SQLException + */ + public String createInviteLink(String sl_id) throws SQLException{ + String invitelink = generateInviteLink(); + sqlUpdate2Param("UPDATE \"Shoppinglist\" SET invitelink = ? WHERE sl_id = ?", invitelink, sl_id); + return invitelink; + } + + /** + * Wenn die Shoppingliste bereits geshared ist wird true zurückgegeben + * @param sl_id Die Liste die geprüft werden soll + * @return True wenn die liste bereits geshared ist + * @throws SQLException + * @throws JSONException + */ + public boolean isShared(String sl_id) throws SQLException, JSONException { + connectDatabase(); + + String SQL = "SELECT row_to_json(\"Shoppinglist\") AS obj FROM \"Shoppinglist\" WHERE sl_id = ?"; + + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, sl_id); + ResultSet rs = pstmt.executeQuery(); + boolean returnBoolean = false; + while(rs.next()){ + JSONObject jsonObject = new JSONObject(rs.getString(1)); + + Log.d("isShared LOG ", jsonObject.getString("invitelink")); + + if(jsonObject.getString("invitelink").equals("null")){ + returnBoolean = false; + }else{ + returnBoolean = true; + } + } + + return returnBoolean; + } + /** * Löscht eine Gruppe von der Tabelle Group und alle items dieser group, desswegen wird aucj die tabelle item geleert + * * @param group_id Die group id welche gelöscht werden soll - * @param sl_id Die Shoppingliste auf der sich die group befindet + * @param sl_id Die Shoppingliste auf der sich die group befindet * @throws SQLException */ public void deleteGroup(String group_id, String sl_id) throws SQLException { @@ -61,12 +175,31 @@ public class Database { sqlUpdate2Param("DELETE FROM \"Group\" WHERE group_id = ? AND sl_id = ?", group_id, sl_id); } + /** + * Gibt den Besitzer einer Shoppingliste zurück + * @param sl_id Shoppingliste von der der Besitzer gefunden werden soll + * @return Die uid des Besitzers + */ + public String getShoppinglistOwner(String sl_id) throws SQLException { + connectDatabase(); + + String SQL = "Select username from \"Shoppinglist_admin\" WHERE sl_id = ?"; + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, sl_id); + ResultSet rs = pstmt.executeQuery(); + + String owner = rs.getString(1); + + return owner; + } + /** * Bearbeitet ein Item in der Datenbank - * @param item_id Daqs zu bearbeitende item + * + * @param item_id Daqs zu bearbeitende item * @param group_id Die gruppe in dem da sitem ist - * @param sl_id die shoppinglist in dem das item ist - * @param newname der neue name + * @param sl_id die shoppinglist in dem das item ist + * @param newname der neue name * @param newcount die neue anzahl * @throws SQLException * @throws JSONException @@ -91,9 +224,10 @@ public class Database { /** * Löscht ein item - * @param item_id Item id + * + * @param item_id Item id * @param group_id group id - * @param sl_id shoppoinglist id + * @param sl_id shoppoinglist id */ public void deleteItem(String item_id, String group_id, String sl_id) throws SQLException { sqlUpdate3Param("DELETE FROM \"Item\" WHERE item_id = ? AND group_id = ? AND sl_id = ?", item_id, group_id, sl_id); @@ -101,10 +235,11 @@ public class Database { /** * Fügt ein neues Item der Datenbank hinzu + * * @param group_id Die group id in der das neue item angezeigt werden soll - * @param sl_id Die Shoppingliste in der das neue item nagezeigt werden soll - * @param name Der name des Items - * @param count Die anzahl des Items + * @param sl_id Die Shoppingliste in der das neue item nagezeigt werden soll + * @param name Der name des Items + * @param count Die anzahl des Items * @throws SQLException */ public void addItem(String group_id, String sl_id, String name, int count) throws SQLException { @@ -154,6 +289,7 @@ public class Database { /** * Hollt ein bestimtes item + * * @param item_id Die sl_id in der das item ist * @return * @throws SQLException @@ -349,6 +485,35 @@ public class Database { } + /** + * Verbindet sich mit dem server + * Holt alle shared shoppinglists des users + * @param uid User von dem die Shared Shoppinglists geholt werden sollen + * @return Die Shared Shoppinglisten des Users + * @throws SQLException + * @throws JSONException + */ + public List getSharedShoppinglists(String uid) throws SQLException, JSONException { + connectDatabase(); + String SQL = "SELECT row_to_json(\"Shoppinglist\") AS obj FROM \"Shoppinglist\" JOIN \"Shoppinglist_member\" USING (sl_id) WHERE username = ?"; + PreparedStatement pstmt = conect.prepareStatement(SQL); + pstmt.setString(1, uid); + ResultSet rs = pstmt.executeQuery(); + System.out.println(uid); + + ArrayList shoppinglistArrayList = new ArrayList(); + + while(rs.next()){ + String shoppinglist = rs.getString(1); + JSONObject jsonObject = new JSONObject(shoppinglist); + + shoppinglistArrayList.add(new Shoppinglist(jsonObject.getString("sl_id"), jsonObject.getString("name"), jsonObject.getString("description"), jsonObject.getString("invitelink"), jsonObject.getString("color"))); + } + + + return (List) shoppinglistArrayList; + } + /** * Hoolt alle groups und items der list und erstelt ein Detail objekt von jeder group. Die detail objekte kommen in eine List @@ -382,8 +547,9 @@ public class Database { /** * Holt alle Items einer bestimmten gruppe + * * @param group_id Gruppe welche geholt werden soll - * @param sl_id Die Shoppinglist in der sich die gruppe befindet + * @param sl_id Die Shoppinglist in der sich die gruppe befindet * @return * @throws SQLException * @throws JSONException @@ -392,9 +558,9 @@ public class Database { List
details = getListDetails(sl_id); ArrayList result = new ArrayList(); - for(Details d : details){ + for (Details d : details) { String group_idtmp = d.getGroup().getGroup_id(); - if(group_idtmp.equals(group_id)){ + if (group_idtmp.equals(group_id)) { result = d.getItems(); } } @@ -428,6 +594,7 @@ public class Database { private String generateGroupId() { return generateSL_Id(); } + /** * Generiert eine neue 8 stellige item_id * @@ -437,6 +604,15 @@ public class Database { return generateSL_Id(); } + /** + * Generiert eine neue 8 stellige inviteLink + * + * @return Neue intielink + */ + public String generateInviteLink() { + return generateSL_Id(); + } + /** * Holt alle Items einer bestimmten shoppingliste, angegeben durch die shoppinglist id diff --git a/app/src/main/java/at/smartshopper/smartshopper/shoppinglist/ShoppinglistAdapter.java b/app/src/main/java/at/smartshopper/smartshopper/shoppinglist/ShoppinglistAdapter.java index dc7e6b3..5a6288d 100644 --- a/app/src/main/java/at/smartshopper/smartshopper/shoppinglist/ShoppinglistAdapter.java +++ b/app/src/main/java/at/smartshopper/smartshopper/shoppinglist/ShoppinglistAdapter.java @@ -14,6 +14,7 @@ import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; @@ -31,6 +32,7 @@ public class ShoppinglistAdapter extends RecyclerView.Adapter + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/share.png b/app/src/main/res/drawable-hdpi/share.png new file mode 100644 index 0000000..312a6ee Binary files /dev/null and b/app/src/main/res/drawable-hdpi/share.png differ diff --git a/app/src/main/res/drawable-mdpi/share.png b/app/src/main/res/drawable-mdpi/share.png new file mode 100644 index 0000000..b789b68 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/share.png differ diff --git a/app/src/main/res/drawable-xhdpi/share.png b/app/src/main/res/drawable-xhdpi/share.png new file mode 100644 index 0000000..a50c5a8 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/share.png differ diff --git a/app/src/main/res/drawable-xxhdpi/share.png b/app/src/main/res/drawable-xxhdpi/share.png new file mode 100644 index 0000000..6dab223 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/share.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/share.png b/app/src/main/res/drawable-xxxhdpi/share.png new file mode 100644 index 0000000..ff4132d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/share.png differ diff --git a/app/src/main/res/layout/activity_dash.xml b/app/src/main/res/layout/activity_dash.xml index fdd25b3..e62986d 100644 --- a/app/src/main/res/layout/activity_dash.xml +++ b/app/src/main/res/layout/activity_dash.xml @@ -75,10 +75,19 @@ android:layout_height="match_parent" android:orientation="vertical"> - + android:layout_height="match_parent"> + + + + + + diff --git a/app/src/main/res/layout/add_share.xml b/app/src/main/res/layout/add_share.xml new file mode 100644 index 0000000..72a33ff --- /dev/null +++ b/app/src/main/res/layout/add_share.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +