From 521bf52e7946c0fda6e2c4008579181458514e9b Mon Sep 17 00:00:00 2001 From: Marius Metzger Date: Sat, 31 Jan 2015 21:04:25 +0100 Subject: [PATCH] Finished File Upload GUI --- .../replaymod/api/client/FileUploader.java | 70 +++++++++++---- .../replaymod/gui/GuiConstants.java | 2 + .../replaymod/gui/online/GuiLoginPrompt.java | 11 ++- .../replaymod/gui/online/GuiReplayCenter.java | 4 +- .../replaymod/gui/online/GuiUploadFile.java | 89 ++++++++++++++----- 5 files changed, 130 insertions(+), 46 deletions(-) diff --git a/src/main/java/eu/crushedpixel/replaymod/api/client/FileUploader.java b/src/main/java/eu/crushedpixel/replaymod/api/client/FileUploader.java index e6151637..97f85f2c 100644 --- a/src/main/java/eu/crushedpixel/replaymod/api/client/FileUploader.java +++ b/src/main/java/eu/crushedpixel/replaymod/api/client/FileUploader.java @@ -14,7 +14,9 @@ import java.util.HashMap; import com.google.gson.Gson; import com.google.gson.JsonParser; +import eu.crushedpixel.replaymod.api.client.holders.ApiError; import eu.crushedpixel.replaymod.api.client.holders.Category; +import eu.crushedpixel.replaymod.gui.online.GuiUploadFile; public class FileUploader { private static Gson gson = new Gson(); @@ -23,29 +25,34 @@ public class FileUploader { private boolean uploading = false; private long filesize; private long current; - + private String attachmentName = "file"; private String attachmentFileName = "file.mcpr"; private String crlf = "\r\n"; private String twoHyphens = "--"; + private boolean cancel = false; + private String boundary = "*****"; + private GuiUploadFile parent; //private CountingHttpEntity counter; - public void uploadFile(String auth, String filename, File file, Category category) throws IOException, ApiException, RuntimeException { + public void uploadFile(GuiUploadFile gui, String auth, String filename, File file, Category category) throws IOException, ApiException, RuntimeException { + parent = gui; + gui.onStartUploading(); + filesize = 0; + if(uploading) throw new RuntimeException("FileUploader is already uploading"); uploading = true; - filesize = file.length(); - current = 0; - String postData = "?auth="+auth+"&category="+category.getId()+"&name="+filename; - + String url = "http://ReplayMod.com/api/upload_file"+postData; HttpURLConnection con = (HttpURLConnection)new URL(url).openConnection(); con.setUseCaches(false); con.setDoOutput(true); con.setRequestMethod("POST"); + con.setChunkedStreamingMode(1024); con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Cache-Control", "no-cache"); con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + this.boundary); @@ -60,45 +67,70 @@ public class FileUploader { request.writeBytes(this.twoHyphens + this.boundary + this.crlf); request.writeBytes("Content-Disposition: form-data; name=\"" + this.attachmentName + "\";filename=\"" + this.attachmentFileName + "\"" + this.crlf); request.writeBytes(this.crlf); - + byte[] buf = new byte[1024]; FileInputStream fis = new FileInputStream(file); + filesize = fis.getChannel().size(); + current = 0; int len; while((len = fis.read(buf)) != -1) { request.write(buf); current += len; + if(cancel) { + uploading = false; + current = 0; + cancel = false; + parent.onFinishUploading(false, "Upload has been canceled"); + fis.close(); + return; + } } fis.close(); - + request.writeBytes(this.crlf); request.writeBytes(this.twoHyphens + this.boundary + this.twoHyphens + this.crlf); - + request.flush(); request.close(); - - int responseCode = ((HttpURLConnection)con).getResponseCode(); + + boolean success = false; + int responseCode = con.getResponseCode(); InputStream is = null; if(responseCode == 200) { + success = true; is = con.getInputStream(); } else { is = con.getErrorStream(); } - + BufferedReader r = new BufferedReader(new InputStreamReader(is)); - - while(r.ready()) { - System.out.println(r.readLine()); + + String info = null; + if(responseCode != 200) { + ApiError error = new ApiError(-1, "An unknown error occured"); + while(r.ready()) { + error = gson.fromJson(r.readLine(), ApiError.class); + } + info = error.getDesc(); } - - System.out.println(responseCode); // Should be 200 con.disconnect(); - + + parent.onFinishUploading(success, info); + uploading = false; } public float getUploadProgress() { - if(!uploading) return 0.1f; + if(!uploading || filesize == 0) return 0; return (float)((double)current/(double)filesize); } + + public boolean isUploading() { + return uploading; + } + + public void cancelUploading() { + cancel = true; + } } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/GuiConstants.java b/src/main/java/eu/crushedpixel/replaymod/gui/GuiConstants.java index f8eb5099..6c1fa11a 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/GuiConstants.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/GuiConstants.java @@ -15,6 +15,8 @@ public class GuiConstants { public static final int UPLOAD_START_BUTTON = 3003; public static final int UPLOAD_CANCEL_BUTTON = 3004; public static final int UPLOAD_BACK_BUTTON = 3005; + public static final int UPLOAD_INFO_FIELD = 3006; + public static final int UPLOAD_TAG_INPUT = 3007; public static final int REPLAY_OPTIONS_BUTTON_ID = 8000; diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiLoginPrompt.java b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiLoginPrompt.java index b3d86a31..c78f7a25 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiLoginPrompt.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiLoginPrompt.java @@ -66,13 +66,18 @@ public class GuiLoginPrompt extends GuiScreen { //Authenticate textState = LOGGING_IN; - mc.addScheduledTask(new Runnable() { + new Thread(new Runnable() { @Override public void run() { switch(AuthenticationHandler.authenticate(username.getText(), password.getText())) { case AuthenticationHandler.SUCCESS: textState = EMPTY; - mc.displayGuiScreen(successScreen); + mc.addScheduledTask(new Runnable() { + @Override + public void run() { + mc.displayGuiScreen(successScreen); + } + }); break; case AuthenticationHandler.INVALID: textState = INVALID_LOGIN; @@ -82,7 +87,7 @@ public class GuiLoginPrompt extends GuiScreen { break; } } - }); + }).start(); } } else if(button.id == GuiConstants.LOGIN_CANCEL_BUTTON) { mc.displayGuiScreen(parent); diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiReplayCenter.java b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiReplayCenter.java index 055f0823..68f1e259 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiReplayCenter.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiReplayCenter.java @@ -56,7 +56,7 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback { int w2 = w/buttonBar.size(); int x = 15+(w2*i); - b.xPosition = x; + b.xPosition = x+2; b.yPosition = 20; b.width = w2-4; @@ -83,7 +83,7 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback { int w2 = w/bottomBar.size(); int x = 15+(w2*i); - b.xPosition = x; + b.xPosition = x+2; b.yPosition = height-30; b.width = w2-4; diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiUploadFile.java b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiUploadFile.java index c41f7b88..793c08b2 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiUploadFile.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiUploadFile.java @@ -44,7 +44,7 @@ import eu.crushedpixel.replaymod.utils.ImageUtils; public class GuiUploadFile extends GuiScreen { - private GuiTextField fileTitleInput; + private GuiTextField fileTitleInput, tagInput, messageTextField; private GuiButton categoryButton, startUploadButton, cancelUploadButton, backButton; private Gson gson = new Gson(); @@ -52,7 +52,7 @@ public class GuiUploadFile extends GuiScreen { private File replayFile; private ReplayMetaData metaData; private BufferedImage thumb; - + private FileUploader uploader = new FileUploader(); private Category category = Category.MINIGAME; @@ -127,13 +127,12 @@ public class GuiUploadFile extends GuiScreen { public void initGui() { if(replayFile == null) return; - fileTitleInput = new GuiTextField(GuiConstants.UPLOAD_NAME_INPUT, fontRendererObj, 200, 21, 120, 20); + fileTitleInput = new GuiTextField(GuiConstants.UPLOAD_NAME_INPUT, fontRendererObj, (this.width/2)+20+10, 21, Math.min(200, this.width-20-260), 20); String fname = FilenameUtils.getBaseName(replayFile.getAbsolutePath()); fileTitleInput.setText(fname); - - categoryButton = new GuiButton(GuiConstants.UPLOAD_CATEGORY_BUTTON, 200, 80, "Category: "+category.toNiceString()); - categoryButton.width = 120; + categoryButton = new GuiButton(GuiConstants.UPLOAD_CATEGORY_BUTTON, (this.width/2)+20+10-1, 80, "Category: "+category.toNiceString()); + categoryButton.width = Math.min(202, this.width-20-260+2); buttonList.add(categoryButton); List bottomBar = new ArrayList(); @@ -146,6 +145,12 @@ public class GuiUploadFile extends GuiScreen { backButton = new GuiButton(GuiConstants.UPLOAD_BACK_BUTTON, 0, 0, "Back"); bottomBar.add(backButton); + + messageTextField = new GuiTextField(GuiConstants.UPLOAD_INFO_FIELD, fontRendererObj, 20, height-80, width-40, 20); + messageTextField.setEnabled(true); + messageTextField.setFocused(false); + + tagInput = new GuiTextField(GuiConstants.UPLOAD_TAG_INPUT, fontRendererObj, (this.width/2)+20+10, 110, Math.min(200, this.width-20-260), 20); int i = 0; for(GuiButton b : bottomBar) { @@ -153,7 +158,7 @@ public class GuiUploadFile extends GuiScreen { int w2 = w/bottomBar.size(); int x = 15+(w2*i); - b.xPosition = x; + b.xPosition = x+2; b.yPosition = height-30; b.width = w2-4; @@ -175,22 +180,25 @@ public class GuiUploadFile extends GuiScreen { } else if(button.id == GuiConstants.UPLOAD_BACK_BUTTON) { mc.displayGuiScreen(new GuiMainMenu()); } else if(button.id == GuiConstants.UPLOAD_START_BUTTON) { - mc.addScheduledTask(new Runnable() { + final String name = fileTitleInput.getText().trim(); + new Thread(new Runnable() { @Override public void run() { try { - uploader.uploadFile(AuthenticationHandler.getKey(), fileTitleInput.getText().trim(), replayFile, category); + uploader.uploadFile(GuiUploadFile.this, AuthenticationHandler.getKey(), name, replayFile, category); } catch (ApiException e) { //TODO: Error handling e.printStackTrace(); - mc.displayGuiScreen(new GuiMainMenu()); + //mc.displayGuiScreen(new GuiMainMenu()); } catch (RuntimeException e) { e.printStackTrace(); - mc.displayGuiScreen(new GuiMainMenu()); + //mc.displayGuiScreen(new GuiMainMenu()); } catch (IOException e) { e.printStackTrace(); } } - }); + }).start(); + } else if(button.id == GuiConstants.UPLOAD_CANCEL_BUTTON) { + uploader.cancelUploading(); } } @@ -198,12 +206,12 @@ public class GuiUploadFile extends GuiScreen { public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); - drawString(fontRendererObj, metaData.getServerName(), 200, 50, Color.GRAY.getRGB()); + drawString(fontRendererObj, metaData.getServerName(), (this.width/2)+20+10, 50, Color.GRAY.getRGB()); drawString(fontRendererObj, "Duration: "+String.format("%02dm%02ds", TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()), TimeUnit.MILLISECONDS.toSeconds(metaData.getDuration()) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration())) - ), 200, 65, Color.GRAY.getRGB()); + ), (this.width/2)+20+10, 65, Color.GRAY.getRGB()); drawCenteredString(fontRendererObj, "Upload File", this.width/2, 5, Color.WHITE.getRGB()); @@ -217,20 +225,28 @@ public class GuiUploadFile extends GuiScreen { } mc.getTextureManager().bindTexture(textureResource); //Will be freed by the ResourceHelper - Gui.drawScaledCustomSizeModalRect(20, 20, 0, 0, 1280, 720, 57*3, 32*3, 1280, 720); + int wid = (this.width)/2; + int hei = Math.round(wid*(720f/1280f)); + Gui.drawScaledCustomSizeModalRect(19, 20, 0, 0, 1280, 720, wid, hei, 1280, 720); } fileTitleInput.drawTextBox(); - + messageTextField.drawTextBox(); + tagInput.drawTextBox(); + super.drawScreen(mouseX, mouseY, partialTicks); - this.drawRect(20, this.height-100, width-20, this.height-80, Color.BLACK.getRGB()); - this.drawRect(22, this.height-98, width-22, this.height-82, Color.WHITE.getRGB()); + this.drawRect(19, this.height-52, width-19, this.height-37, Color.BLACK.getRGB()); + this.drawRect(21, this.height-50, width-21, this.height-39, Color.WHITE.getRGB()); - int width = this.width-22 - 22; - float w = width*uploader.getUploadProgress(); + int width = this.width-21 - 21; + float prog = uploader.getUploadProgress(); + float w = width*prog; - this.drawRect(22, this.height-98, Math.round(22+w), this.height-82, Color.RED.getRGB()); + this.drawRect(21, this.height-50, Math.round(21+w), this.height-39, Color.RED.getRGB()); + + String perc = (int)Math.floor(prog*100)+"%"; + fontRendererObj.drawString(perc, this.width/2 - fontRendererObj.getStringWidth(perc)/2, this.height-48, Color.BLACK.getRGB()); } @Override @@ -257,8 +273,37 @@ public class GuiUploadFile extends GuiScreen { fileTitleInput.textboxKeyTyped(typedChar, keyCode); } + if(uploader.isUploading()) { + startUploadButton.enabled = false; + } else { + startUploadButton.enabled = (!(fileTitleInput.getText().trim().length() < 5 || fileTitleInput.getText().trim().length() > 30 || + p.matcher(fileTitleInput.getText()).find())); + } + } + + public void onStartUploading() { + startUploadButton.enabled = false; + cancelUploadButton.enabled = true; + backButton.enabled = false; + categoryButton.enabled = false; + fileTitleInput.setEnabled(false); + messageTextField.setText("Uploading..."); + messageTextField.setTextColor(Color.WHITE.getRGB()); + } + + public void onFinishUploading(boolean success, String info) { startUploadButton.enabled = (!(fileTitleInput.getText().trim().length() < 5 || fileTitleInput.getText().trim().length() > 30 || p.matcher(fileTitleInput.getText()).find())); - + cancelUploadButton.enabled = false; + backButton.enabled = true; + categoryButton.enabled = true; + fileTitleInput.setEnabled(true); + if(success) { + messageTextField.setText("File has been successfully uploaded"); + messageTextField.setTextColor(Color.GREEN.getRGB()); + } else { + messageTextField.setText(info); + messageTextField.setTextColor(Color.RED.getRGB()); + } } }