✨ feat: Improve multiple file download function.
This commit is contained in:
parent
da459e2253
commit
95481b89f0
2 changed files with 94 additions and 14 deletions
|
|
@ -13,6 +13,7 @@ import io.vertx.core.http.CookieSameSite;
|
|||
import io.vertx.core.http.HttpMethod;
|
||||
import io.vertx.core.http.HttpServerOptions;
|
||||
import io.vertx.core.http.HttpServerResponse;
|
||||
import io.vertx.core.json.JsonArray;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.healthchecks.HealthCheckHandler;
|
||||
import io.vertx.ext.healthchecks.HealthChecks;
|
||||
|
|
@ -140,6 +141,7 @@ public class HttpVerticle extends AbstractVerticle {
|
|||
|
||||
router.get("/file/preview").handler(this::handleFilePreview);
|
||||
router.post("/file/start-download").handler(this::handleFileStartDownload);
|
||||
router.post("/file/start-download-multiple").handler(this::handleFileStartDownloadMultiple);
|
||||
router.post("/file/cancel-download").handler(this::handleFileCancelDownload);
|
||||
router.post("/file/toggle-pause-download").handler(this::handleFileTogglePauseDownload);
|
||||
router.post("/file/auto-download").handler(this::handleAutoDownload);
|
||||
|
|
@ -315,11 +317,11 @@ public class HttpVerticle extends AbstractVerticle {
|
|||
}
|
||||
TelegramVerticle telegramVerticle = telegramVerticleOptional.get();
|
||||
telegramVerticle.close(true)
|
||||
.onSuccess(r -> {
|
||||
telegramVerticles.remove(telegramVerticle);
|
||||
sessionTelegramVerticles.entrySet().removeIf(e -> e.getValue().equals(telegramVerticle));
|
||||
ctx.end();
|
||||
});
|
||||
.onSuccess(r -> {
|
||||
telegramVerticles.remove(telegramVerticle);
|
||||
sessionTelegramVerticles.entrySet().removeIf(e -> e.getValue().equals(telegramVerticle));
|
||||
ctx.end();
|
||||
});
|
||||
}
|
||||
|
||||
private void handleTelegrams(RoutingContext ctx) {
|
||||
|
|
@ -511,6 +513,36 @@ public class HttpVerticle extends AbstractVerticle {
|
|||
.onFailure(ctx::fail);
|
||||
}
|
||||
|
||||
private void handleFileStartDownloadMultiple(RoutingContext ctx) {
|
||||
TelegramVerticle telegramVerticle = getTelegramVerticle(ctx);
|
||||
if (telegramVerticle == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject jsonObject = ctx.body().asJsonObject();
|
||||
Long chatId = jsonObject.getLong("chatId");
|
||||
JsonArray files = jsonObject.getJsonArray("files");
|
||||
if (chatId == null || CollUtil.isEmpty(files)) {
|
||||
ctx.fail(400);
|
||||
return;
|
||||
}
|
||||
|
||||
Future.any(files.stream()
|
||||
.map(f -> {
|
||||
JsonObject file = (JsonObject) f;
|
||||
Long messageId = file.getLong("messageId");
|
||||
Integer fileId = file.getInteger("fileId");
|
||||
return telegramVerticle.startDownload(chatId, messageId, fileId);
|
||||
})
|
||||
.toList())
|
||||
.onSuccess(ctx::json)
|
||||
.onFailure(r -> {
|
||||
log.error(r, "Failed to start download multiple files");
|
||||
ctx.json(JsonObject.of("error", "Part of the files failed to start download"));
|
||||
ctx.response().setStatusCode(400).end();
|
||||
});
|
||||
}
|
||||
|
||||
private void handleFileCancelDownload(RoutingContext ctx) {
|
||||
TelegramVerticle telegramVerticle = getTelegramVerticle(ctx);
|
||||
if (telegramVerticle == null) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import {
|
|||
FileAudioIcon,
|
||||
FileIcon,
|
||||
ImageIcon,
|
||||
LoaderCircle,
|
||||
LoaderPinwheel,
|
||||
VideoIcon,
|
||||
} from "lucide-react";
|
||||
|
|
@ -51,6 +52,8 @@ import FileNotFount from "@/components/file-not-found";
|
|||
import FileExtra from "@/components/file-extra";
|
||||
import useIsMobile from "@/hooks/use-is-mobile";
|
||||
import FileStatus from "@/components/file-status";
|
||||
import useSWRMutation from "swr/mutation";
|
||||
import { POST } from "@/lib/api";
|
||||
|
||||
interface FileListProps {
|
||||
accountId: string;
|
||||
|
|
@ -112,6 +115,28 @@ export function FileList({ accountId, chatId }: FileListProps) {
|
|||
);
|
||||
const { filters, handleFilterChange, isLoading, files, handleLoadMore } =
|
||||
useFiles(accountId, chatId);
|
||||
const {
|
||||
trigger: startDownloadMultiple,
|
||||
isMutating: startDownloadMultipleMutating,
|
||||
} = useSWRMutation(
|
||||
"/file/start-download-multiple",
|
||||
(
|
||||
key,
|
||||
{
|
||||
arg,
|
||||
}: {
|
||||
arg: {
|
||||
chatId: number;
|
||||
files: Array<{ messageId: number; fileId: number }>;
|
||||
};
|
||||
},
|
||||
) => POST(key, arg),
|
||||
{
|
||||
onSuccess: () => {
|
||||
setSelectedFiles(new Set());
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
|
|
@ -182,7 +207,13 @@ export function FileList({ accountId, chatId }: FileListProps) {
|
|||
if (selectedFiles.size === files.length) {
|
||||
setSelectedFiles(new Set());
|
||||
} else {
|
||||
setSelectedFiles(new Set(files.map((file) => file.id)));
|
||||
setSelectedFiles(
|
||||
new Set(
|
||||
files
|
||||
.filter((file) => file.downloadStatus === "idle")
|
||||
.map((file) => file.id),
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -296,16 +327,32 @@ export function FileList({ accountId, chatId }: FileListProps) {
|
|||
<Button
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
//TODO implement download selected
|
||||
void startDownloadMultiple({
|
||||
chatId: Number(chatId),
|
||||
files: Array.from(selectedFiles).map((id) => {
|
||||
const file = files.find((f) => f.id === id);
|
||||
return {
|
||||
messageId: file?.messageId ?? 0,
|
||||
fileId: file?.id ?? 0,
|
||||
};
|
||||
}),
|
||||
});
|
||||
}}
|
||||
disabled={Array.from(selectedFiles).every(
|
||||
(id) =>
|
||||
files.find((f) => f.id === id)?.downloadStatus ===
|
||||
"downloading",
|
||||
)}
|
||||
disabled={
|
||||
selectedFiles.size === 0 || startDownloadMultipleMutating
|
||||
}
|
||||
>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Download Selected
|
||||
{startDownloadMultipleMutating ? (
|
||||
<LoaderCircle
|
||||
className="mr-2 h-4 w-4 animate-spin"
|
||||
style={{ strokeWidth: "0.8px" }}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Download Selected
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -350,6 +397,7 @@ export function FileList({ accountId, chatId }: FileListProps) {
|
|||
<Checkbox
|
||||
checked={selectedFiles.has(file.id)}
|
||||
onCheckedChange={() => handleSelectFile(file.id)}
|
||||
disabled={file.downloadStatus !== "idle"}
|
||||
/>
|
||||
</TableCell>
|
||||
{columns.map((col) =>
|
||||
|
|
|
|||
Loading…
Reference in a new issue