From 59c1e4afa858d85a02831ba161d67e86e1960e60 Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Sat, 10 Oct 2020 23:24:32 +0300 Subject: [PATCH] Update net stack: add interruption command. Update UI: add dark theme, created and added navigation panel pattern, updated margins for better view on phones with curved screens (eg. 1+ 8pro) --- app/build.gradle | 4 +- .../ns_usbloader/SettingsActivity.java | 49 ++-- .../ns_usbloader/service/TinfoilNET.java | 275 +++++++++--------- app/src/main/res/color/drawer_item.xml | 5 + .../main/res/drawable-night/side_nav_bar.xml | 17 ++ .../main/res/drawable/ic_donate_yandex.xml | 51 +++- app/src/main/res/drawable/ic_game_pattern.xml | 181 ++++++++++++ app/src/main/res/drawable/side_nav_bar.xml | 26 +- app/src/main/res/layout/activity_main.xml | 4 +- app/src/main/res/layout/content_settings.xml | 2 +- app/src/main/res/layout/nav_header_main.xml | 48 +-- app/src/main/res/layout/nsp_item.xml | 57 ++-- app/src/main/res/values-night/colors.xml | 11 + app/src/main/res/values/colors.xml | 7 +- app/src/main/res/values/dimens.xml | 3 +- app/src/main/res/values/styles.xml | 7 +- 16 files changed, 495 insertions(+), 252 deletions(-) create mode 100644 app/src/main/res/color/drawer_item.xml create mode 100644 app/src/main/res/drawable-night/side_nav_bar.xml create mode 100644 app/src/main/res/drawable/ic_game_pattern.xml create mode 100644 app/src/main/res/values-night/colors.xml diff --git a/app/build.gradle b/app/build.gradle index f39615f..e70ef1c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "com.blogspot.developersu.ns_usbloader" minSdkVersion 15 targetSdkVersion 29 - versionCode 4 - versionName "2.0" + versionCode 5 + versionName "3.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" android.defaultConfig.vectorDrawables.useSupportLibrary = true } diff --git a/app/src/main/java/com/blogspot/developersu/ns_usbloader/SettingsActivity.java b/app/src/main/java/com/blogspot/developersu/ns_usbloader/SettingsActivity.java index 5cb9012..0c8266f 100644 --- a/app/src/main/java/com/blogspot/developersu/ns_usbloader/SettingsActivity.java +++ b/app/src/main/java/com/blogspot/developersu/ns_usbloader/SettingsActivity.java @@ -9,16 +9,16 @@ import android.text.Spanned; import android.text.TextWatcher; import android.view.MenuItem; import android.widget.EditText; -import android.widget.Switch; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.Toolbar; public class SettingsActivity extends AppCompatActivity { private EditText nsIp; private EditText servAddr; private EditText servPort; - private Switch autoDetectIp; + private SwitchCompat autoDetectIp; @Override public boolean onOptionsItemSelected(MenuItem item){ @@ -68,7 +68,7 @@ public class SettingsActivity extends AppCompatActivity { if (! editable.toString().matches("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")) nsIp.setTextColor(Color.RED); else - nsIp.setTextColor(Color.BLACK); + nsIp.setTextColor(getResources().getColor(R.color.defaultTextColor)); } }); servAddr.addTextChangedListener(new TextWatcher() { @@ -83,7 +83,7 @@ public class SettingsActivity extends AppCompatActivity { if (! editable.toString().matches("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")) nsIp.setTextColor(Color.RED); else - nsIp.setTextColor(Color.BLACK); + nsIp.setTextColor(getResources().getColor(R.color.defaultTextColor)); } }); @@ -99,10 +99,10 @@ public class SettingsActivity extends AppCompatActivity { String contentString = editable.toString(); //Log.i("LPR", contentString); if (contentString.matches("^\\d{1,5}")){ - if (Integer.valueOf(contentString) < 1024) + if (Integer.parseInt(contentString) < 1024) servPort.setTextColor(Color.RED); else - servPort.setTextColor(Color.BLACK); + servPort.setTextColor(getResources().getColor(R.color.defaultTextColor)); } } }); @@ -123,33 +123,30 @@ public class SettingsActivity extends AppCompatActivity { spEditor.putString("SServerIP", servAddr.getText().toString()); final String contentString = servPort.getText().toString(); - if (contentString.matches("^\\d{1,5}") && (Integer.valueOf(contentString) >= 1024)){ - spEditor.putInt("SServerPort", Integer.valueOf(servPort.getText().toString())); + if (contentString.matches("^\\d{1,5}") && (Integer.parseInt(contentString) >= 1024)){ + spEditor.putInt("SServerPort", Integer.parseInt(servPort.getText().toString())); } spEditor.apply(); } - private static InputFilter inputFilterForIP = new InputFilter() { - @Override - public CharSequence filter(CharSequence charSequence, int start, int end, Spanned destination, int dStart, int dEnd) { - if (end > start) { - String destTxt = destination.toString(); - String resultingTxt = destTxt.substring(0, dStart) + - charSequence.subSequence(start, end) + - destTxt.substring(dEnd); - if (! resultingTxt.matches ("^\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3})?)?)?)?)?)?")) - return ""; - else { - String[] splits = resultingTxt.split("\\."); - for (String split : splits) { - if (Integer.valueOf(split) > 255) - return ""; - } + private static InputFilter inputFilterForIP = (charSequence, start, end, destination, dStart, dEnd) -> { + if (end > start) { + String destTxt = destination.toString(); + String resultingTxt = destTxt.substring(0, dStart) + + charSequence.subSequence(start, end) + + destTxt.substring(dEnd); + if (! resultingTxt.matches ("^\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3})?)?)?)?)?)?")) + return ""; + else { + String[] splits = resultingTxt.split("\\."); + for (String split : splits) { + if (Integer.parseInt(split) > 255) + return ""; } } - return null; } + return null; }; private static InputFilter inputFilterForPort = new InputFilter() { @@ -162,7 +159,7 @@ public class SettingsActivity extends AppCompatActivity { destTxt.substring(dEnd); if (!resultingTxt.matches ("^[0-9]+")) return ""; - if (Integer.valueOf(resultingTxt) > 65535) + if (Integer.parseInt(resultingTxt) > 65535) return ""; } return null; diff --git a/app/src/main/java/com/blogspot/developersu/ns_usbloader/service/TinfoilNET.java b/app/src/main/java/com/blogspot/developersu/ns_usbloader/service/TinfoilNET.java index 389a278..f495408 100644 --- a/app/src/main/java/com/blogspot/developersu/ns_usbloader/service/TinfoilNET.java +++ b/app/src/main/java/com/blogspot/developersu/ns_usbloader/service/TinfoilNET.java @@ -30,7 +30,7 @@ import static android.content.Context.WIFI_SERVICE; class TinfoilNET extends TransferTask { - private HashMap nspMap; + private HashMap files; private Socket handShakeSocket; private ServerSocket serverSocket; @@ -42,6 +42,7 @@ class TinfoilNET extends TransferTask { private String phoneIp; private int phonePort; + private boolean jobInProgress = true; @Override void cancel(){ @@ -68,11 +69,10 @@ class TinfoilNET extends TransferTask { this.phoneIp = phoneIp; this.phonePort = phonePort; - this.nspMap = new HashMap<>(); + this.files = new HashMap<>(); // Collect and encode NSP files list - for (NSPElement nspElem : nspElements) - nspMap.put(URLEncoder.encode(nspElem.getFilename(), "UTF-8").replaceAll("\\+", "%20"), nspElem); // replace + to %20 + files.put(URLEncoder.encode(nspElem.getFilename(), "UTF-8").replaceAll("\\+", "%20"), nspElem); // replace + to %20 // Resolve IP if (phoneIp.isEmpty()) @@ -102,13 +102,28 @@ class TinfoilNET extends TransferTask { @Override boolean run(){ - if (interrupt) - return false; - // Create string that we'll send to TF and which initiates chain - StringBuilder myStrBuilder; + try { + if (interrupt) + return false; - myStrBuilder = new StringBuilder(); - for (String fileNameEncoded : nspMap.keySet()) { + byte[] handshakeCommand = buildHandshakeContent().getBytes(); // android's .getBytes() default == UTF8 // Follow the + byte[] handshakeCommandSize = ByteBuffer.allocate(4).putInt(handshakeCommand.length).array(); // defining order ; Integer size = 4 bytes + + sendHandshake(handshakeCommandSize, handshakeCommand); + + serveRequestsLoop(); + } + catch (Exception e){ + close(true); + issueDescription = "NET: Unable to connect to NS and send files list: "+e.getMessage(); + return true; + } + close(false); + return true; + } + private String buildHandshakeContent(){ + StringBuilder myStrBuilder = new StringBuilder(); + for (String fileNameEncoded : files.keySet()) { myStrBuilder.append(phoneIp); myStrBuilder.append(':'); myStrBuilder.append(phonePort); @@ -116,201 +131,183 @@ class TinfoilNET extends TransferTask { myStrBuilder.append(fileNameEncoded); myStrBuilder.append('\n'); } - - byte[] nspListNames = myStrBuilder.toString().getBytes(); // android's .getBytes() default == UTF8 // Follow the - byte[] nspListSize = ByteBuffer.allocate(4).putInt(nspListNames.length).array(); // defining order ; Integer size = 4 bytes - + return myStrBuilder.toString(); + } + private void sendHandshake(byte[] handshakeCommandSize, byte[] handshakeCommand) throws Exception{ try { handShakeSocket = new Socket(); handShakeSocket.connect(new InetSocketAddress(InetAddress.getByName(nsIp), 2000), 1000); // e.g. 1sec OutputStream os = handShakeSocket.getOutputStream(); - os.write(nspListSize); - os.write(nspListNames); + os.write(handshakeCommandSize); + os.write(handshakeCommand); os.flush(); handShakeSocket.close(); } catch (IOException uhe){ - issueDescription = "NET: Unable to connect to NS and send files list. Returned: "+uhe.getMessage(); - close(true); - return true; + throw new Exception("NET: Unable to send files list: "+uhe.getMessage()); } - // Go transfer - work_routine: - while (true){ - try { - Socket clientSocket = serverSocket.accept(); - - BufferedReader br = new BufferedReader( - new InputStreamReader(clientSocket.getInputStream()) - ); - - currSockOS = clientSocket.getOutputStream(); - currSockPW = new PrintWriter(new OutputStreamWriter(currSockOS)); - - String line; - LinkedList tcpPacket = new LinkedList<>(); - - while ((line = br.readLine()) != null) { - //System.out.println(line); // Debug - if (line.trim().isEmpty()) { // If TCP packet is ended - if (handleRequest(tcpPacket)) // Proceed required things - break work_routine; - tcpPacket.clear(); // Clear data and wait for next TCP packet - } - else - tcpPacket.add(line); // Otherwise collect data - } - clientSocket.close(); - } - catch (IOException ioe){ // If server socket closed, then client socket also closed. - break; - } - } - close(false); - return true; } + private void serveRequestsLoop() throws Exception{ + while (jobInProgress){ + Socket clientSocket = serverSocket.accept(); + + BufferedReader br = new BufferedReader( + new InputStreamReader(clientSocket.getInputStream()) + ); + + currSockOS = clientSocket.getOutputStream(); + currSockPW = new PrintWriter(new OutputStreamWriter(currSockOS)); + + String line; + LinkedList tcpPacket = new LinkedList<>(); + + while ((line = br.readLine()) != null) { + if (line.trim().isEmpty()) { // If TCP packet is ended + handleRequest(tcpPacket); // Proceed required things + tcpPacket.clear(); // Clear data and wait for next TCP packet + } + else + tcpPacket.add(line); // Otherwise collect data + } + clientSocket.close(); + } + } // 200 206 400 (inv range) 404 416 (Range Not Satisfiable ) /** * Handle requests - * @return true if failed * */ - private boolean handleRequest(LinkedList packet){ + private void handleRequest(LinkedList packet) throws Exception{ + if (packet.get(0).startsWith("DROP")){ + jobInProgress = false; + return; + } + String reqFileName = packet.get(0).replaceAll("(^[A-z\\s]+/)|(\\s+?.*$)", ""); - if (! nspMap.containsKey(reqFileName)){ - currSockPW.write(NETPacket.getCode404()); - currSockPW.flush(); - issueDescription = "NET: File "+reqFileName+" doesn't exists or have 0 size. Returning 404"; - return true; + if (! files.containsKey(reqFileName)){ + writeToSocket(NETPacket.getCode404()); + return; } - NSPElement requestedElement = nspMap.get(reqFileName); + NSPElement requestedElement = files.get(reqFileName); long reqFileSize = requestedElement.getSize(); if (reqFileSize == 0){ // well.. tell 404 if file exists with 0 length is against standard, but saves time - currSockPW.write(NETPacket.getCode404()); - currSockPW.flush(); - issueDescription = "NET: File "+reqFileName+" doesn't exists or have 0 size. Returning 404"; - return true; + writeToSocket(NETPacket.getCode404()); + requestedElement.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); + return; } if (packet.get(0).startsWith("HEAD")){ - currSockPW.write(NETPacket.getCode200(reqFileSize)); - currSockPW.flush(); - return false; + writeToSocket(NETPacket.getCode200(reqFileSize)); + return; } if (packet.get(0).startsWith("GET")) { for (String line: packet) { - if (line.toLowerCase().startsWith("range")) { //todo: fix - try { - String[] rangeStr = line.toLowerCase().replaceAll("^range:\\s+?bytes=", "").split("-", 2); - if (!rangeStr[0].isEmpty() && !rangeStr[1].isEmpty()) { // If both ranges defined: Read requested - if (Long.parseLong(rangeStr[0]) > Long.parseLong(rangeStr[1])){ // If start bytes greater then end bytes - currSockPW.write(NETPacket.getCode400()); - currSockPW.flush(); - issueDescription = "NET: Requested range for "+requestedElement.getFilename()+" is incorrect. Returning 400"; - requestedElement.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); - return true; - } - if (writeToSocket(requestedElement, Long.parseLong(rangeStr[0]), Long.parseLong(rangeStr[1]))) // DO WRITE - return true; - } - else if (!rangeStr[0].isEmpty()) { // If only START defined: Read all - if (writeToSocket(requestedElement, Long.parseLong(rangeStr[0]), reqFileSize)) // DO WRITE - return true; - } - else if (!rangeStr[1].isEmpty()) { // If only END defined: Try to read last 500 bytes - if (reqFileSize > 500){ - if (writeToSocket(requestedElement, reqFileSize-500, reqFileSize)) // DO WRITE - return true; - } - else { // If file smaller than 500 bytes - currSockPW.write(NETPacket.getCode416()); - currSockPW.flush(); - issueDescription = "NET: File size requested for "+requestedElement.getFilename()+" while actual size of it: "+requestedElement.getSize()+". Returning 416"; - requestedElement.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); - return true; - } - } - else { - currSockPW.write(NETPacket.getCode400()); // If Range not defined: like "Range: bytes=-" - currSockPW.flush(); - issueDescription = "NET: Requested range for "+requestedElement.getFilename()+" is incorrect (empty start & end). Returning 400"; - requestedElement.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); - return true; - } - break; - } - catch (NumberFormatException nfe){ - currSockPW.write(NETPacket.getCode400()); - currSockPW.flush(); - issueDescription = "NET: Requested range for "+requestedElement.getFilename()+" has incorrect format. Returning 400\n\t"+nfe.getMessage(); - requestedElement.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); - return true; - } + if (line.toLowerCase().startsWith("range")){ + parseGETrange(requestedElement, reqFileSize, line); + return; } } } - return false; } - /** - * Send files. - * */ - private boolean writeToSocket(NSPElement nspElem, long start, long end){ - if (interrupt) - return true; - currSockPW.write(NETPacket.getCode206(nspElem.getSize(), start, end)); + + private void parseGETrange(NSPElement requestedElement, long fileSize, String rangeDirective) throws Exception{ + try { + String[] rangeStr = rangeDirective.toLowerCase().replaceAll("^range:\\s+?bytes=", "").split("-", 2); + + if (! rangeStr[0].isEmpty()){ + if (rangeStr[1].isEmpty()) { + writeToSocket(requestedElement, Long.parseLong(rangeStr[0]), fileSize); + return; + } + + long fromRange = Long.parseLong(rangeStr[0]); + long toRange = Long.parseLong(rangeStr[1]); + if (fromRange > toRange){ // If start bytes greater then end bytes + writeToSocket(NETPacket.getCode400()); + requestedElement.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); + return; + } + writeToSocket(requestedElement, fromRange, toRange); + return; + } + + if (rangeStr[1].isEmpty()) { + writeToSocket(NETPacket.getCode400()); // If Range not defined: like "Range: bytes=-" + requestedElement.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); + return; + } + + if (fileSize > 500) { + writeToSocket(requestedElement, fileSize - 500, fileSize); + return; + } + // If file smaller than 500 bytes + writeToSocket(NETPacket.getCode416()); + requestedElement.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); + } + catch (NumberFormatException nfe){ + writeToSocket(NETPacket.getCode400()); + requestedElement.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); + throw new Exception("NET: Requested range for "+requestedElement.getFilename()+" has incorrect format. Returning 400\n\t"+nfe.getMessage()); + } + } + /** Send commands */ + private void writeToSocket(String string) { + currSockPW.write(string); currSockPW.flush(); + } + /** Send files */ + private void writeToSocket(NSPElement nspElem, long start, long end) throws Exception{ + if (interrupt){ + throw new Exception("Interrupted by user"); + } + writeToSocket(NETPacket.getCode206(nspElem.getSize(), start, end)); try{ long count = end - start + 1; // Meeh. Somehow it works - InputStream elementIS = context.getContentResolver().openInputStream(nspElem.getUri()); - if (elementIS == null) { - issueDescription = "NET Unable to obtain InputStream"; - return true; + InputStream elementInputStream = context.getContentResolver().openInputStream(nspElem.getUri()); + if (elementInputStream == null) { + throw new Exception("NET Unable to obtain input stream"); } - BufferedInputStream bis = new BufferedInputStream(elementIS); + BufferedInputStream bis = new BufferedInputStream(elementInputStream); - int readPice = 8388608; // = 8Mb + int readPice = 4194304;//8388608;// = 8Mb (1024 is slow) byte[] byteBuf; if (bis.skip(start) != start){ - issueDescription = "NET: Unable to skip requested range."; nspElem.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); - return true; + throw new Exception("NET: Unable to skip requested range"); } long currentOffset = 0; while (currentOffset < count){ if (interrupt) - return true; + throw new Exception("Interrupted by user"); if ((currentOffset+readPice) >= count){ readPice = (int) (count - currentOffset); } byteBuf = new byte[readPice]; if (bis.read(byteBuf) != readPice){ - issueDescription = "NET: Reading of nspElem stream suddenly ended."; - return true; + throw new Exception("NET: Reading from file stream suddenly ended"); } currSockOS.write(byteBuf); currentOffset += readPice; - updateProgressBar((int) ((currentOffset+1)/(count/100+1))); - + updateProgressBar((int) ((double)currentOffset/((double)count/100.0))); } currSockOS.flush(); // TODO: check if this really needed. bis.close(); resetProgressBar(); } catch (IOException ioe){ - issueDescription = "NET: File transmission failed. Returned: "+ioe.getMessage(); nspElem.setStatus(context.getResources().getString(R.string.status_failed_to_upload)); // TODO: REDUNDANT? - return true; + throw new Exception("NET: File transmission failed. Returned: "+ioe.getMessage()); } - return false; } /** * Close when done diff --git a/app/src/main/res/color/drawer_item.xml b/app/src/main/res/color/drawer_item.xml new file mode 100644 index 0000000..9e27952 --- /dev/null +++ b/app/src/main/res/color/drawer_item.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-night/side_nav_bar.xml b/app/src/main/res/drawable-night/side_nav_bar.xml new file mode 100644 index 0000000..3b0c69b --- /dev/null +++ b/app/src/main/res/drawable-night/side_nav_bar.xml @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_donate_yandex.xml b/app/src/main/res/drawable/ic_donate_yandex.xml index 94313ac..52567f6 100644 --- a/app/src/main/res/drawable/ic_donate_yandex.xml +++ b/app/src/main/res/drawable/ic_donate_yandex.xml @@ -1,41 +1,60 @@ + + android:fillType="nonZero" + android:fillAlpha="0.996"/> + android:fillType="nonZero" + android:fillAlpha="0.996"/> + android:fillType="nonZero" + android:fillAlpha="0.996"/> + android:fillType="nonZero" + android:fillAlpha="0.996"/> + android:fillType="nonZero" + android:fillAlpha="0.996"/> + android:fillType="nonZero" + android:fillAlpha="0.996"/> + android:fillType="nonZero" + android:fillAlpha="0.996"/> diff --git a/app/src/main/res/drawable/ic_game_pattern.xml b/app/src/main/res/drawable/ic_game_pattern.xml new file mode 100644 index 0000000..956ef20 --- /dev/null +++ b/app/src/main/res/drawable/ic_game_pattern.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml index 6ca1e14..c751097 100644 --- a/app/src/main/res/drawable/side_nav_bar.xml +++ b/app/src/main/res/drawable/side_nav_bar.xml @@ -1,9 +1,17 @@ - - - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 8aa408f..f0a7808 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -15,11 +15,13 @@ \ No newline at end of file diff --git a/app/src/main/res/layout/content_settings.xml b/app/src/main/res/layout/content_settings.xml index 3a3911a..83e52d2 100644 --- a/app/src/main/res/layout/content_settings.xml +++ b/app/src/main/res/layout/content_settings.xml @@ -48,7 +48,7 @@ android:inputType="number" /> - + + + --> diff --git a/app/src/main/res/layout/nsp_item.xml b/app/src/main/res/layout/nsp_item.xml index b182210..002aceb 100644 --- a/app/src/main/res/layout/nsp_item.xml +++ b/app/src/main/res/layout/nsp_item.xml @@ -4,44 +4,43 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:padding="2dp" - app:cardElevation="@dimen/cardview_default_elevation"> + android:layout_margin="2dp"> - + android:layout_height="match_parent" + android:layout_margin="3dp" + android:orientation="vertical"> + android:text="Name Long" /> - + - - + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml new file mode 100644 index 0000000..7723b84 --- /dev/null +++ b/app/src/main/res/values-night/colors.xml @@ -0,0 +1,11 @@ + + + #ce0000 + #b20101 + #00c8fc + #52acff + #eea11e + #00c8fc + #ffffff + #1c1c1c + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index fa241fc..1b1787f 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,8 +1,11 @@ - #ec0000 - #ce0000 + #ce0000 + #b20101 #00c8fc #52acff #eea11e + #ce0000 + #000000 + #1c1c1c diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 9b7eea8..05ae9f7 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -3,6 +3,7 @@ 16dp 16dp 8dp - 150dp + 170dp + 304dp 16dp \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 8a84ead..6370d58 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,10 +1,9 @@ - -