Add possibility to send tips
The context menu now contains an entry to send tips. The menu opens a dialog, which displays the current token balance and allows the input of the number of tokens to tip.
This commit is contained in:
parent
ebf36cb594
commit
c614aebba7
|
@ -144,6 +144,10 @@ public class Model {
|
||||||
return Chaturbate.INSTANCE.getMasterPlaylist(getName());
|
return Chaturbate.INSTANCE.getMasterPlaylist(getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void receiveTip(int tokens) throws IOException {
|
||||||
|
Chaturbate.INSTANCE.sendTip(getName(), tokens);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
@ -215,6 +219,25 @@ public class Model {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendTip(String name, int tokens) throws IOException {
|
||||||
|
RequestBody body = new FormBody.Builder()
|
||||||
|
.add("csrfmiddlewaretoken", client.getToken())
|
||||||
|
.add("tip_amount", Integer.toString(tokens))
|
||||||
|
.add("tip_room_type", "public")
|
||||||
|
.build();
|
||||||
|
Request req = new Request.Builder()
|
||||||
|
.url("https://chaturbate.com/tipping/send_tip/"+name+"/")
|
||||||
|
.post(body)
|
||||||
|
.addHeader("Referer", "https://chaturbate.com/"+name+"/")
|
||||||
|
.addHeader("X-Requested-With", "XMLHttpRequest")
|
||||||
|
.build();
|
||||||
|
try(Response response = client.execute(req, true)) {
|
||||||
|
if(!response.isSuccessful()) {
|
||||||
|
throw new IOException(response.code() + " " + response.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private StreamInfo getStreamInfo(String modelName) throws IOException, ExecutionException {
|
private StreamInfo getStreamInfo(String modelName) throws IOException, ExecutionException {
|
||||||
return streamInfoCache.get(modelName);
|
return streamInfoCache.get(modelName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,6 +326,35 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
clipboard.setContent(content);
|
clipboard.setContent(content);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
MenuItem sendTip = new MenuItem("Send Tip");
|
||||||
|
sendTip.setOnAction((e) -> {
|
||||||
|
TipDialog tipDialog = new TipDialog(cell.getModel());
|
||||||
|
tipDialog.showAndWait();
|
||||||
|
String tipText = tipDialog.getResult();
|
||||||
|
if(tipText != null) {
|
||||||
|
if(tipText.matches("[1-9]\\d*")) {
|
||||||
|
int tokens = Integer.parseInt(tipText);
|
||||||
|
try {
|
||||||
|
cell.getModel().receiveTip(tokens);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR);
|
||||||
|
alert.setTitle("Error");
|
||||||
|
alert.setHeaderText("Couldn't send tip");
|
||||||
|
alert.setContentText("An error occured while sending tip: " + e1.getLocalizedMessage());
|
||||||
|
alert.showAndWait();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR);
|
||||||
|
alert.setTitle("Error");
|
||||||
|
alert.setHeaderText("Couldn't send tip");
|
||||||
|
alert.setContentText("You entered an invalid amount of tokens");
|
||||||
|
alert.showAndWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
String username = Config.getInstance().getSettings().username;
|
||||||
|
sendTip.setDisable(username == null || username.trim().isEmpty());
|
||||||
|
|
||||||
// check, if other cells are selected, too. in that case, we have to disable menu item, which make sense only for
|
// check, if other cells are selected, too. in that case, we have to disable menu item, which make sense only for
|
||||||
// single selections. but only do that, if the popup has been triggered on a selected cell. otherwise remove the
|
// single selections. but only do that, if the popup has been triggered on a selected cell. otherwise remove the
|
||||||
// selection and show the normal menu
|
// selection and show the normal menu
|
||||||
|
@ -335,6 +364,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
openInPlayer.setDisable(true);
|
openInPlayer.setDisable(true);
|
||||||
}
|
}
|
||||||
copyUrl.setDisable(true);
|
copyUrl.setDisable(true);
|
||||||
|
sendTip.setDisable(true);
|
||||||
} else {
|
} else {
|
||||||
removeSelection();
|
removeSelection();
|
||||||
}
|
}
|
||||||
|
@ -345,7 +375,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
contextMenu.setHideOnEscape(true);
|
contextMenu.setHideOnEscape(true);
|
||||||
contextMenu.setAutoFix(true);
|
contextMenu.setAutoFix(true);
|
||||||
MenuItem followOrUnFollow = this instanceof FollowedTab ? unfollow : follow;
|
MenuItem followOrUnFollow = this instanceof FollowedTab ? unfollow : follow;
|
||||||
contextMenu.getItems().addAll(openInPlayer, startStop , followOrUnFollow, copyUrl);
|
contextMenu.getItems().addAll(openInPlayer, startStop , followOrUnFollow, copyUrl, sendTip);
|
||||||
return contextMenu;
|
return contextMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package ctbrec.ui;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import ctbrec.Config;
|
||||||
|
import ctbrec.HttpClient;
|
||||||
|
import ctbrec.Model;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.TextInputDialog;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class TipDialog extends TextInputDialog {
|
||||||
|
|
||||||
|
private static final transient Logger LOG = LoggerFactory.getLogger(TipDialog.class);
|
||||||
|
|
||||||
|
public TipDialog(Model model) {
|
||||||
|
setTitle("Send Tip");
|
||||||
|
loadTokenBalance();
|
||||||
|
setHeaderText("Loading token balance…");
|
||||||
|
setContentText("Amount of tokens to tip:");
|
||||||
|
setResizable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadTokenBalance() {
|
||||||
|
Task<Integer> task = new Task<Integer>() {
|
||||||
|
@Override
|
||||||
|
protected Integer call() throws Exception {
|
||||||
|
String username = Config.getInstance().getSettings().username;
|
||||||
|
if (username == null || username.trim().isEmpty()) {
|
||||||
|
throw new IOException("Not logged in");
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = "https://chaturbate.com/p/" + username + "/";
|
||||||
|
HttpClient client = HttpClient.getInstance();
|
||||||
|
Request req = new Request.Builder().url(url).build();
|
||||||
|
Response resp = client.execute(req, true);
|
||||||
|
if (resp.isSuccessful()) {
|
||||||
|
String profilePage = resp.body().string();
|
||||||
|
String tokenText = HtmlParser.getText(profilePage, "span.tokencount");
|
||||||
|
int tokens = Integer.parseInt(tokenText);
|
||||||
|
return tokens;
|
||||||
|
} else {
|
||||||
|
throw new IOException("HTTP response: " + resp.code() + " - " + resp.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
try {
|
||||||
|
int tokens = get();
|
||||||
|
Platform.runLater(() -> setHeaderText("Current token balance: " + tokens));
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
LOG.error("Couldn't retrieve account balance", e);
|
||||||
|
showErrorDialog(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new Thread(task).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showErrorDialog(Throwable throwable) {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR);
|
||||||
|
alert.setTitle("Error");
|
||||||
|
alert.setHeaderText("Couldn't retrieve token balance");
|
||||||
|
alert.setContentText("Error while loading your token balance: " + throwable.getLocalizedMessage());
|
||||||
|
alert.showAndWait();
|
||||||
|
TipDialog.this.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue