This commit is contained in:
2025-09-08 11:09:22 +03:30
parent 7a5eb0a8ab
commit 41c30aff7b
4 changed files with 32 additions and 17 deletions
+14 -11
View File
@@ -1,29 +1,32 @@
module org.to.telegramfinalproject { module org.to.telegramfinalproject {
requires javafx.controls; requires javafx.controls;
requires javafx.fxml; requires javafx.fxml;
requires javafx.graphics; // بهتره اضافه باشه
requires javafx.media;
requires javafx.web; requires javafx.web;
requires org.json;
requires java.sql;
requires java.desktop;
// لایبرری‌های جانبی — اگر واقعاً در مسیر ماژول هستند
requires org.controlsfx.controls; requires org.controlsfx.controls;
requires com.dlsc.formsfx; requires com.dlsc.formsfx;
requires net.synedra.validatorfx; requires net.synedra.validatorfx;
requires org.kordamp.ikonli.javafx; requires org.kordamp.ikonli.javafx;
requires org.kordamp.bootstrapfx.core; requires org.kordamp.bootstrapfx.core;
requires eu.hansolo.tilesfx; requires eu.hansolo.tilesfx;
requires org.json;
requires java.sql;
requires java.desktop;
requires spark.core;
requires javax.servlet.api;
requires mp3agic; requires mp3agic;
requires jdk.internal.le; requires spark.core; // فقط اگر واقعاً استفاده می‌کنی
requires javafx.media; requires javax.servlet.api; // فقط اگر واقعاً استفاده می‌کنی
// FXML کنترلرها در این پکیج‌اند: // کنترلرها/کلاس‌هایی که FXML به آن‌ها دسترسی بازتابی دارد
opens org.to.telegramfinalproject.UI to javafx.fxml; opens org.to.telegramfinalproject.UI to javafx.fxml;
// اگر FXML از کلاس‌های Client هم استفاده می‌کند:
opens org.to.telegramfinalproject.Client to javafx.fxml; opens org.to.telegramfinalproject.Client to javafx.fxml;
opens org.to.telegramfinalproject.Models to javafx.fxml; // اگر مدل‌ها داخل FXML مصرف می‌شوند
// فقط اگر لازم است از بیرون به این API‌ها کامپایل شود: // اگر پکیج‌هایی را می‌خواهی خارج از ماژول در دسترس قرار دهی
exports org.to.telegramfinalproject.UI;
exports org.to.telegramfinalproject.Client; exports org.to.telegramfinalproject.Client;
// ⚠️ عمداً NOT exporting/opens ریشه‌ی پکیج، چون کلاس ندارد. exports org.to.telegramfinalproject.Models;
} }
@@ -206,11 +206,9 @@ public class AddMembersController {
private Image loadAvatar(String path) { private Image loadAvatar(String path) {
try { try {
// 1) اگر ریسورس داخلی باشد
var in = getClass().getResourceAsStream(path); var in = getClass().getResourceAsStream(path);
if (in != null) return new Image(in); if (in != null) return new Image(in);
// 2) اگر URL کامل یا file URI
return new Image(path, true); return new Image(path, true);
} catch (Exception e) { } catch (Exception e) {
return new Image( return new Image(
@@ -233,7 +231,6 @@ public class AddMembersController {
List<String> ids = selectedContacts.stream().map(Contact::getId).toList(); List<String> ids = selectedContacts.stream().map(Contact::getId).toList();
// تلاش برای batch
JSONObject batchReq = new JSONObject() JSONObject batchReq = new JSONObject()
.put("action", "add_members_to_group") .put("action", "add_members_to_group")
.put("group_id", groupInternalId.toString()) .put("group_id", groupInternalId.toString())
@@ -248,11 +245,10 @@ public class AddMembersController {
return; return;
} }
// fallback: تک‌به‌تک
boolean allOk = true; boolean allOk = true;
for (String uid : ids) { for (String uid : ids) {
JSONObject single = new JSONObject() JSONObject single = new JSONObject()
.put("action", "add_member_to_group") .put("action", "add_members_to_group")
.put("group_id", groupInternalId.toString()) .put("group_id", groupInternalId.toString())
.put("user_id", uid); .put("user_id", uid);
JSONObject r = ActionHandler.sendWithResponse(single); JSONObject r = ActionHandler.sendWithResponse(single);
@@ -14,6 +14,8 @@ import org.to.telegramfinalproject.Client.ActionHandler;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@@ -116,13 +118,27 @@ public class ManageGroupController {
groupIdField.setText(originalGroupId); groupIdField.setText(originalGroupId);
if (!originalImageUrl.isBlank()) { if (!originalImageUrl.isBlank()) {
groupImage.setImage(new Image(originalImageUrl, true)); String uri = resolveLocalUri(originalImageUrl);
if (uri != null) {
groupImage.setImage(new Image(uri, true));
}
} }
adminCount.setText(String.valueOf(countRole(data, "admin") + 1)); adminCount.setText(String.valueOf(countRole(data, "admin") + 1));
memberCount.setText(String.valueOf(countRole(data, "member") + Integer.parseInt(adminCount.getText()))); memberCount.setText(String.valueOf(countRole(data, "member") + Integer.parseInt(adminCount.getText())));
} }
private String resolveLocalUri(String raw) {
if (raw == null || raw.isBlank()) return null;
if (raw.startsWith("file:/") || raw.startsWith("http")) return raw;
Path base = Paths.get(System.getProperty("user.dir"), "uploads");
Path resolved = base.resolve(raw.startsWith("/") ? raw.substring(1) : raw)
.normalize();
return resolved.toUri().toString(); // file:///C:/.../uploads/avatars/2025-09-05/...
}
private int countRole(JSONObject groupData, String role) { private int countRole(JSONObject groupData, String role) {
var arr = groupData.optJSONArray("members"); var arr = groupData.optJSONArray("members");
if (arr == null) return 0; if (arr == null) return 0;
Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB