Skip to content

Commit e2da7ee

Browse files
committed
logic done
1 parent 48d7cb7 commit e2da7ee

File tree

5 files changed

+131
-3
lines changed

5 files changed

+131
-3
lines changed

pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
<artifactId>javafx-fxml</artifactId>
4646
<version>${javafx.version}</version>
4747
</dependency>
48+
49+
4850
</dependencies>
4951
<build>
5052
<plugins>

src/main/java/com/example/ChatController.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import javafx.fxml.FXML;
44
import javafx.scene.control.ListView;
55
import javafx.scene.control.TextField;
6+
import javafx.application.Platform;
67

78
public class ChatController {
89

@@ -14,6 +15,7 @@ public class ChatController {
1415

1516
private final ChatModel model = new ChatModel();
1617

18+
1719
@FXML
1820
private void onSend() {
1921
String message = inputField.getText().trim();
@@ -23,4 +25,18 @@ private void onSend() {
2325
inputField.clear();
2426
}
2527
}
28+
29+
30+
@FXML
31+
private void initialize(){
32+
model.subscribe(msg -> {
33+
Platform.runLater(() -> messagesList.getItems().add("Friend: " + msg));
34+
});
35+
}
36+
37+
38+
39+
40+
41+
2642
}
Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,117 @@
11
package com.example;
22

3+
import javafx.application.Platform;
4+
5+
import java.io.BufferedReader;
6+
import java.io.InputStreamReader;
7+
import java.net.URI;
8+
import java.net.http.HttpClient;
9+
import java.net.http.HttpRequest;
10+
import java.net.http.HttpResponse;
11+
import java.util.Collections;
12+
import java.util.Set;
13+
import java.util.UUID;
14+
import java.util.concurrent.ConcurrentHashMap;
15+
import java.util.function.Consumer;
16+
import java.util.regex.Matcher;
17+
import java.util.regex.Pattern;
18+
319
public class ChatModel {
420

21+
private final String sendUrl;
22+
private final String subscribeUrl;
23+
private final String clientId;
24+
private final Set<String> sentMessages = Collections.newSetFromMap(new ConcurrentHashMap<>());
25+
26+
public ChatModel() {
27+
String topic = System.getenv().getOrDefault("NTFY_TOPIC", "https://ntfy.sh/newchatroom3");
28+
29+
sendUrl = topic;
30+
subscribeUrl = topic + "/sse";
31+
clientId = UUID.randomUUID().toString();
32+
}
33+
534
public void sendMessage(String message) {
6-
// TODO: send POST JSON to ntfy
7-
System.out.println("Sending message: " + message);
35+
sentMessages.add(message);
36+
37+
new Thread(() -> {
38+
try { Thread.sleep(5000); } catch (Exception ignored) {}
39+
sentMessages.remove(message);
40+
}).start();
41+
42+
HttpClient client = HttpClient.newHttpClient();
43+
44+
HttpRequest request = HttpRequest.newBuilder()
45+
.uri(URI.create(sendUrl))
46+
.header("Content-Type", "application/json")
47+
.header("X-Client-ID", clientId)
48+
.header("Title", "Friend: ")
49+
.POST(HttpRequest.BodyPublishers.ofString(message))
50+
.build();
51+
52+
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
53+
.thenAccept(response -> System.out.println("Sent, status=" + response.statusCode()))
54+
.exceptionally(e -> { e.printStackTrace(); return null; });
855
}
56+
57+
58+
public void subscribe(Consumer<String> onMessageReceived) {
59+
HttpClient client = HttpClient.newHttpClient();
60+
HttpRequest request = HttpRequest.newBuilder()
61+
.uri(URI.create(subscribeUrl))
62+
.header("Accept", "text/event-stream")
63+
.build();
64+
65+
client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream())
66+
.thenAccept(response -> {
67+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body()))) {
68+
String line;
69+
boolean firstMessageSkipped = false;
70+
while ((line = reader.readLine()) != null) {
71+
if (line.startsWith("data:")) {
72+
if (!firstMessageSkipped) {
73+
firstMessageSkipped = true;
74+
continue;
75+
}
76+
77+
String raw = line.substring(5).trim();
78+
String msg = parseMessage(raw);
79+
80+
if (msg != null && !sentMessages.contains(msg)) {
81+
Platform.runLater(() -> onMessageReceived.accept(msg));
82+
}
83+
}
84+
}
85+
} catch (Exception e) {
86+
e.printStackTrace();
87+
}
88+
})
89+
.exceptionally(e -> { e.printStackTrace(); return null; });
90+
}
91+
92+
private String parseMessage(String data) {
93+
try {
94+
Matcher eventMatcher = Pattern.compile("\"event\"\\s*:\\s*\"(.*?)\"").matcher(data);
95+
if (eventMatcher.find()) {
96+
String event = eventMatcher.group(1);
97+
98+
if (!"message".equals(event)) {
99+
return null;
100+
}
101+
}
102+
103+
Matcher msgMatcher = Pattern.compile("\"message\"\\s*:\\s*\"(.*?)\"").matcher(data);
104+
if (msgMatcher.find()) {
105+
return msgMatcher.group(1).replace("\\\"", "\"");
106+
}
107+
} catch (Exception ignored) {}
108+
109+
return null;
110+
}
111+
112+
113+
9114
}
115+
116+
117+

src/main/java/com/example/HelloFX.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public void start(Stage stage) throws Exception {
1313
FXMLLoader fxmlLoader = new FXMLLoader(HelloFX.class.getResource("chat-view.fxml"));
1414
Parent root = fxmlLoader.load();
1515
Scene scene = new Scene(root, 640, 480);
16-
stage.setTitle("Hello MVC");
16+
stage.setTitle("Chat App");
1717
stage.setScene(scene);
1818
stage.show();
1919
}

src/main/java/module-info.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module hellofx {
22
requires javafx.controls;
33
requires javafx.fxml;
4+
requires java.net.http;
5+
46

57
opens com.example to javafx.fxml;
68
exports com.example;

0 commit comments

Comments
 (0)