mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 08:49:40 -05:00
Breaking changes:
'Gift': changed from class to enum, so now you can handle
incoming gifts in switch
`Events`
- new:
onGiftComboFinished
- Removed:
onGiftBrodcast
- Rename:
onGiftMessage -> onGift
onRoomPinMessage -> onRoomPin
onRoomMessage -> onRoom
onLinkMessage -> onLink
onBarrageMessage -> onBarrage
onPollMessage -> onPoll
onShopMessage -> onShop
onDetectMessage -> onDetect
`GiftManager`
added:
registerGift
findById
findByName
getGifts
removed:
getActiveGifts
This commit is contained in:
36
Tools-EventsWebViewer/pom.xml
Normal file
36
Tools-EventsWebViewer/pom.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>TikTokLiveJava</artifactId>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<version>0.0.25-Release</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>Tools-EventsWebViewer</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.javalin</groupId>
|
||||
<artifactId>javalin</artifactId>
|
||||
<version>5.6.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>2.0.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||
<artifactId>Tools-EventsCollector</artifactId>
|
||||
<version>0.0.25-Release</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.github.jwdeveloper.tiktok.webviewer;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.webviewer.handlers.TikTokHandler;
|
||||
import io.javalin.Javalin;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
|
||||
var manager = new TikTokManager();
|
||||
var app = Javalin.create(config ->
|
||||
{
|
||||
config.plugins.enableCors(corsContainer ->
|
||||
{
|
||||
corsContainer.add(corsPluginConfig ->
|
||||
{
|
||||
corsPluginConfig.allowHost("http://localhost:5500");
|
||||
});
|
||||
});
|
||||
config.staticFiles.add("/public");
|
||||
}).start(8001);
|
||||
|
||||
var handler = new TikTokHandler(manager);
|
||||
app.get("/tiktok/connect", handler::connect);
|
||||
app.get("/tiktok/disconnect", handler::disconnect);
|
||||
app.get("/tiktok/events", handler::events);
|
||||
app.get("/tiktok/events/message", handler::eventMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package io.github.jwdeveloper.tiktok.webviewer;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.client.MessageCollector;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.client.TikTokMessageCollectorClient;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.client.TikTokMessagessCollectorBuilder;
|
||||
import io.github.jwdeveloper.tiktok.tools.util.MessageUtil;
|
||||
import lombok.Value;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class TikTokManager {
|
||||
TikTokMessagessCollectorBuilder client;
|
||||
MessageCollector msgCollector;
|
||||
|
||||
public TikTokManager() {
|
||||
msgCollector = new MessageCollector("web");
|
||||
}
|
||||
|
||||
public void connect(String name) throws SQLException {
|
||||
disconnect();
|
||||
client = TikTokMessageCollectorClient.create(msgCollector, "web").addUser(name);
|
||||
client.buildAndRun();
|
||||
}
|
||||
|
||||
public List<String> getEventsNames() {
|
||||
return msgCollector.getMessages().keySet().stream().toList();
|
||||
}
|
||||
|
||||
public List<String> getEventMessages(String eventName) {
|
||||
return msgCollector.getMessages().get(eventName).stream().map(MessageCollector.MessageData::getEventData).toList();
|
||||
}
|
||||
|
||||
|
||||
public MessageDto getMessage(String event) throws InvalidProtocolBufferException {
|
||||
var eventData = msgCollector.getMessages().get(event);
|
||||
var messages = eventData.stream().toList();
|
||||
var random = new Random();
|
||||
var index = random.nextInt(messages.size()-1);
|
||||
var msg = messages.get(index);
|
||||
|
||||
|
||||
var bytes = Base64.getDecoder().decode(msg.getEventData());
|
||||
var content = MessageUtil.getContent(event,bytes);
|
||||
return new MessageDto(content, msg.getEventData(), event);
|
||||
}
|
||||
|
||||
@Value
|
||||
public class MessageDto {
|
||||
String content;
|
||||
String base64;
|
||||
String eventName;
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
client.stop();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package io.github.jwdeveloper.tiktok.webviewer.handlers;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import io.github.jwdeveloper.tiktok.webviewer.TikTokManager;
|
||||
import io.javalin.http.Context;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class TikTokHandler {
|
||||
private final TikTokManager tikTokManager;
|
||||
|
||||
public TikTokHandler(TikTokManager tikTokManager) {
|
||||
this.tikTokManager = tikTokManager;
|
||||
}
|
||||
|
||||
|
||||
public void connect(Context context) throws SQLException {
|
||||
String name = context.queryParam("name");
|
||||
if (name.equals(" ")) {
|
||||
context.result("Name can not be empty");
|
||||
context.status(400);
|
||||
return;
|
||||
}
|
||||
tikTokManager.connect(name);
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void disconnect(Context context) throws SQLException {
|
||||
tikTokManager.disconnect();
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void events(Context context) throws SQLException {
|
||||
var events = tikTokManager.getEventsNames();
|
||||
var gson = new Gson();
|
||||
var result = gson.toJson(events);
|
||||
context.result(result);
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void eventMessage(Context context) throws InvalidProtocolBufferException {
|
||||
String name = context.queryParam("eventName");
|
||||
var result = tikTokManager.getMessage(name);
|
||||
var gson = new Gson();
|
||||
context.result(gson.toJson(result));
|
||||
}
|
||||
}
|
||||
226
Tools-EventsWebViewer/src/main/resources/public/index.html
Normal file
226
Tools-EventsWebViewer/src/main/resources/public/index.html
Normal file
@@ -0,0 +1,226 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<title>Bootstrap Styled Javalin App</title>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/editor/editor.main.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/loader.min.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
body, html {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #121212; /* Dark background */
|
||||
}
|
||||
#app {
|
||||
height: 100vh; /* 100% of the viewport height */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.btn-primary
|
||||
{
|
||||
background-color: #2c2c2c;
|
||||
border-color: #2c2c2c;
|
||||
}
|
||||
.btn-primary:hover
|
||||
{
|
||||
background-color: #474747;
|
||||
border-color: #474747;
|
||||
}
|
||||
|
||||
#editor {
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.editor-container
|
||||
{
|
||||
|
||||
padding: 10em;
|
||||
}
|
||||
.list-group-item:hover
|
||||
{
|
||||
background-color: #474747;
|
||||
color: azure;
|
||||
cursor: pointer;
|
||||
}
|
||||
.list-group-item
|
||||
{
|
||||
background-color: #2c2c2c;
|
||||
color: azure;
|
||||
border-color: #252424;
|
||||
}
|
||||
.content {
|
||||
flex-grow: 1; /* Takes up the remaining space */
|
||||
display: flex;
|
||||
}
|
||||
.col-md-10, .col-md-2 {
|
||||
padding: 0; /* Remove default padding */
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/editor/editor.main.css">
|
||||
|
||||
<!-- Load Monaco Editor's main loader script -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/loader.min.js"></script>
|
||||
|
||||
<!-- Configure the loader -->
|
||||
<script>
|
||||
require.config({
|
||||
paths: {'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs'}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Load the editor -->
|
||||
<script>
|
||||
var editor;
|
||||
require(['vs/editor/editor.main'], function() {
|
||||
editor = monaco.editor.create(document.getElementById('editor'), {
|
||||
value: [
|
||||
'function x() {',
|
||||
'\tconsole.log("Hello world!");',
|
||||
'}'
|
||||
].join('\n'),
|
||||
language: 'json',
|
||||
theme: 'vs-dark'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</head>
|
||||
<body class="bg-dark">
|
||||
|
||||
<div id="app" class="container-fluid mt-5">
|
||||
<div >
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Name:</label>
|
||||
<input type="text" id="name" name="name" class="form-control">
|
||||
</div>
|
||||
<button type="button" onclick="connect()" class="btn btn-primary">Connect</button>
|
||||
<button type="button" onclick="disconnect()" class="btn btn-primary">Disconnect</button>
|
||||
<button onclick="showEvents()" class="btn btn-primary">Show Events</button>
|
||||
</div>
|
||||
|
||||
<div class="content row mt-5">
|
||||
|
||||
<div class="col-md-2 ">
|
||||
<ul id="eventList" class="list-group" style="max-height: 100%; overflow-y: auto;">
|
||||
<!-- List items will be added dynamically -->
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-10 editor-container ">
|
||||
<nav aria-label="Page navigation example">
|
||||
<ul class="pagination">
|
||||
<li class="page-item btn-primary"><a class="page-link" href="#">Previous</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">1</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">2</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">3</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">Next</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div id="editor"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
async function connect() {
|
||||
let name = document.getElementById('name').value;
|
||||
name = "bangbetmenygy"
|
||||
let response = await fetch(`http://localhost:8001/tiktok/connect?name=${name}`);
|
||||
let greeting = await response.text();
|
||||
console.log("connect",greeting);
|
||||
connected = true;
|
||||
}
|
||||
async function disconnect() {
|
||||
let response = await fetch(`http://localhost:8001/tiktok/disconnect`);
|
||||
let greeting = await response.text();
|
||||
console.log("disconnect",greeting);
|
||||
connected = false;
|
||||
}
|
||||
|
||||
async function loadMessage(event)
|
||||
{
|
||||
let response = await fetch(`http://localhost:8001/tiktok/events/message?eventName=${event}`);
|
||||
let json = await response.text();
|
||||
// json = json.replace(/\/n/g, "\n");
|
||||
let root= JSON.parse(json);
|
||||
console.log(root)
|
||||
|
||||
editor.setValue(root.content);
|
||||
}
|
||||
|
||||
async function showEvents() {
|
||||
let response = await fetch(`http://localhost:8001/tiktok/events`);
|
||||
let json = await response.text();
|
||||
console.log("events:",json);
|
||||
let events= JSON.parse(json);
|
||||
|
||||
$("#eventList").empty();
|
||||
$.each(events, function(index, event) {
|
||||
let listItem = $('<li>', {
|
||||
class: 'list-group-item',
|
||||
text: event
|
||||
}).click(async function()
|
||||
{
|
||||
await loadMessage(event);
|
||||
});
|
||||
$("#eventList").append(listItem);
|
||||
});
|
||||
}
|
||||
|
||||
async function loop()
|
||||
{
|
||||
if(!connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
console.log("updating");
|
||||
await showEvents();
|
||||
}
|
||||
|
||||
var connected = false;
|
||||
setInterval(loop, 1000)
|
||||
showEvents()
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user