Skip to content

Commit 41e2c8f

Browse files
committed
Add Personal Library
Correction for Proxy - MediaMtx
1 parent 9f7a679 commit 41e2c8f

23 files changed

Lines changed: 563 additions & 128 deletions

server/server.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ httpServer.on("upgrade", (req, socket, head) => {
272272
try {
273273
wss.emit("connection", ws, req);
274274
} catch (error: any) {
275-
console.error("Proxy error:", error);
275+
console.error("Proxy Upgrade http error:", error);
276276
const err = error as Error; // Cast error to Error
277277
console.error(
278278
"Client WebSocket details:",
@@ -294,7 +294,7 @@ if (httpsServer) {
294294
try {
295295
wss.emit("connection", ws, req);
296296
} catch (error: any) {
297-
console.error("Proxy error:", error);
297+
console.error("Proxy Upgrade https error:", error);
298298
const err = error as Error; // Cast error to Error
299299
console.error(
300300
"Client WebSocket details:",
@@ -578,6 +578,11 @@ app.get("/getLocalIP", async (req, res) => {
578578
res.status(200).json({ ips: getLocalIPAddress() });
579579
});
580580

581+
app.use((req, res, next) => {
582+
console.debug(`📥 Incoming Request: ${req.method} ${req.originalUrl}`);
583+
next();
584+
});
585+
581586
// Proxy route
582587
app.all("*", async (req, res) => {
583588
const controller = new AbortController();
@@ -592,6 +597,7 @@ app.all("*", async (req, res) => {
592597
console.log("Proxy is running");
593598
const { target } = req.query;
594599
console.log("target: ", target);
600+
console.log("originalUrl: ", req.originalUrl);
595601
if (!target) {
596602
// Log the full query object to see all parameters
597603
console.log("Request error:", req.originalUrl);
@@ -601,6 +607,11 @@ app.all("*", async (req, res) => {
601607
// Extract the last target from the query string if it's recursive
602608
const lastTarget = new URL(target).searchParams.get("target") || target;
603609
console.log("target: ", lastTarget);
610+
const urlLastTarget = new URL(target);
611+
console.log("target port: ", urlLastTarget.port);
612+
613+
// Assign the correct agent based on `lastTarget`
614+
const agent = getAgentForUrl(lastTarget);
604615

605616
// Prepare headers, removing problematic ones
606617
const filteredHeaders = Object.fromEntries(
@@ -638,9 +649,6 @@ app.all("*", async (req, res) => {
638649
signal?: AbortSignal; // Ensure signal is part of the type
639650
}
640651

641-
// Assign the correct agent based on `lastTarget`
642-
const agent = getAgentForUrl(lastTarget);
643-
644652
const fetchOptions: FetchOptions = {
645653
signal: req.signal ?? controller.signal,
646654
method: req.method ?? "GET", // Fallback to "GET" if req.method is undefined

src/components/DeleteObservationListModal.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ export default function DeleteObjectListModal(props: PropTypes) {
5050
const cloneObjectLists = structuredClone(objectLists);
5151
delete cloneObjectLists[connectionCtx.currentUserObjectListName as string];
5252
setObjectLists(cloneObjectLists);
53+
console.log("saveObjectListsDb", JSON.stringify(cloneObjectLists));
5354
saveObjectListsDb(JSON.stringify(cloneObjectLists));
54-
connectionCtx.setUserCurrentObjectListName(undefined);
55-
saveUserCurrentObjectListNameDb("default");
55+
connectionCtx.setUserCurrentObjectListName("personal");
56+
saveUserCurrentObjectListNameDb("personal");
5657

5758
// close modal
5859
setShowModal(false);

src/components/GotoLists.tsx

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,40 @@ import type { Dispatch, SetStateAction } from "react";
44
import { useTranslation } from "react-i18next";
55
import i18n from "@/i18n";
66

7+
import { AstroObject } from "@/types";
78
import DSOList from "@/components/astroObjects/DSOList";
89
import PlanetsList from "@/components/astroObjects/PlanetsList";
910
import dsoCatalog from "../../data/catalogs/dso_catalog.json";
1011
import { processObjectListOpenNGC } from "@/lib/observation_lists_utils";
1112
import { ConnectionContext } from "@/stores/ConnectionContext";
12-
import { saveCurrentObjectListNameDb } from "@/db/db_utils";
13+
import {
14+
saveCurrentObjectListNameDb,
15+
fetchObjectListByNameDb,
16+
} from "@/db/db_utils";
1317

1418
let dsoObject = processObjectListOpenNGC(dsoCatalog);
15-
console.info("DSO processObjectListOpenNGC");
1619

1720
type PropType = {
1821
objectFavoriteNames: string[];
1922
setObjectFavoriteNames: Dispatch<SetStateAction<string[]>>;
23+
objectPersonalList: AstroObject[];
24+
setObjectPersonalList: Dispatch<SetStateAction<AstroObject[]>>;
2025
setModule: Dispatch<SetStateAction<string | undefined>>;
2126
setErrors: Dispatch<SetStateAction<string | undefined>>;
2227
setSuccess: Dispatch<SetStateAction<string | undefined>>;
2328
};
2429

2530
export default function AutoGoto(props: PropType) {
2631
const { objectFavoriteNames, setObjectFavoriteNames } = props;
32+
const { objectPersonalList, setObjectPersonalList } = props;
2733
const { setModule, setErrors, setSuccess } = props;
34+
2835
const { t } = useTranslation();
2936
// eslint-disable-next-line no-unused-vars
3037
const [selectedLanguage, setSelectedLanguage] = useState<string>("en");
3138

39+
let connectionCtx = useContext(ConnectionContext);
40+
3241
useEffect(() => {
3342
const storedLanguage = localStorage.getItem("language");
3443
if (storedLanguage) {
@@ -37,7 +46,24 @@ export default function AutoGoto(props: PropType) {
3746
}
3847
}, []);
3948

40-
let connectionCtx = useContext(ConnectionContext);
49+
useEffect(() => {
50+
try {
51+
// get objects lists from local storage on page load
52+
console.log("Load personalObjecList on load");
53+
let personalObjecList = fetchObjectListByNameDb("personal");
54+
if (personalObjecList) {
55+
setObjectPersonalList(personalObjecList);
56+
console.log(
57+
"Loaded personalObjecList on load: ",
58+
personalObjecList.length
59+
);
60+
} else {
61+
console.log("No personalObjecList found in DB");
62+
}
63+
} catch (error) {
64+
console.error("Error personalObjecList on load", error);
65+
}
66+
}, []);
4167

4268
function selectListHandler(e: ChangeEvent<HTMLSelectElement>) {
4369
connectionCtx.setCurrentObjectListName(e.target.value);
@@ -108,6 +134,9 @@ export default function AutoGoto(props: PropType) {
108134
objects={dsoObject}
109135
objectFavoriteNames={objectFavoriteNames}
110136
setObjectFavoriteNames={setObjectFavoriteNames}
137+
objectPersonalList={objectPersonalList}
138+
setObjectPersonalList={setObjectPersonalList}
139+
isInObjectPersonalList={false}
111140
setModule={setModule}
112141
setErrors={setErrors}
113142
setSuccess={setSuccess}

src/components/GotoStellarium.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@ type Message = {
3939
type PropType = {
4040
objectFavoriteNames: string[];
4141
setObjectFavoriteNames: Dispatch<SetStateAction<string[]>>;
42+
objectPersonalList: AstroObject[];
43+
setObjectPersonalList: Dispatch<SetStateAction<AstroObject[]>>;
4244
setModule: Dispatch<SetStateAction<string | undefined>>;
4345
setErrors: Dispatch<SetStateAction<string | undefined>>;
4446
setSuccess: Dispatch<SetStateAction<string | undefined>>;
4547
};
4648

4749
export default function ManualGoto(props: PropType) {
4850
const { objectFavoriteNames, setObjectFavoriteNames } = props;
51+
const { objectPersonalList, setObjectPersonalList } = props;
4952
const { setModule, setErrors, setSuccess } = props;
5053
let connectionCtx = useContext(ConnectionContext);
5154
const [RA, setRA] = useState<string | undefined>();
@@ -328,6 +331,9 @@ export default function ManualGoto(props: PropType) {
328331
object={objectNGC}
329332
objectFavoriteNames={objectFavoriteNames}
330333
setObjectFavoriteNames={setObjectFavoriteNames}
334+
objectPersonalList={objectPersonalList}
335+
setObjectPersonalList={setObjectPersonalList}
336+
isInObjectPersonalList={false}
331337
setModule={setModule}
332338
setErrors={setErrors}
333339
setSuccess={setSuccess}

src/components/GotoUserLists.tsx

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,23 @@ import { AstroObject } from "@/types";
1212
import {
1313
fetchObjectListsDb,
1414
fetchObjectListsNamesDb,
15+
fetchObjectListByNameDb,
1516
saveUserCurrentObjectListNameDb,
1617
} from "@/db/db_utils";
1718

1819
type PropType = {
1920
objectFavoriteNames: string[];
2021
setObjectFavoriteNames: Dispatch<SetStateAction<string[]>>;
22+
objectPersonalList: AstroObject[];
23+
setObjectPersonalList: Dispatch<SetStateAction<AstroObject[]>>;
2124
setModule: Dispatch<SetStateAction<string | undefined>>;
2225
setErrors: Dispatch<SetStateAction<string | undefined>>;
2326
setSuccess: Dispatch<SetStateAction<string | undefined>>;
2427
};
2528

2629
export default function GotoUserLists(props: PropType) {
2730
const { objectFavoriteNames, setObjectFavoriteNames } = props;
31+
const { objectPersonalList, setObjectPersonalList } = props;
2832
const { setModule, setErrors, setSuccess } = props;
2933

3034
let connectionCtx = useContext(ConnectionContext);
@@ -35,21 +39,45 @@ export default function GotoUserLists(props: PropType) {
3539
}>({});
3640
const [showImportModal, setShowImportModal] = useState(false);
3741
const [showDeleteModal, setShowDeleteModal] = useState(false);
42+
const [selectPersonalList, setSelectPersonalList] = useState(
43+
connectionCtx.currentUserObjectListName === "personal"
44+
);
45+
46+
useEffect(() => {
47+
try {
48+
// get objects lists from local storage on page load
49+
console.log("Load personalObjecList on load");
50+
let personalObjecList = fetchObjectListByNameDb("personal");
51+
if (personalObjecList) {
52+
setObjectPersonalList(personalObjecList);
53+
console.log(
54+
"Loaded personalObjecList on load: ",
55+
personalObjecList.length
56+
);
57+
} else {
58+
console.log("No personalObjecList found in DB");
59+
}
60+
} catch (error) {
61+
console.error("Error personalObjecList on load", error);
62+
}
63+
}, []);
3864

3965
useEffect(() => {
40-
// get objects lists from local storage on page load
66+
// get objects lists from local storage personal list change
4167
let names = fetchObjectListsNamesDb();
4268
if (names) {
4369
setObjectListsNames(names);
4470
}
4571
let lists = fetchObjectListsDb();
72+
console.log("List Objects", lists);
4673
if (lists) {
4774
setObjectLists(lists);
4875
}
49-
}, []);
76+
}, [objectPersonalList]);
5077

5178
function selectListHandler(e: ChangeEvent<HTMLSelectElement>) {
5279
let listName = e.target.value;
80+
setSelectPersonalList(listName == "personal");
5381
connectionCtx.setUserCurrentObjectListName(listName);
5482
saveUserCurrentObjectListNameDb(listName);
5583
}
@@ -96,10 +124,15 @@ export default function GotoUserLists(props: PropType) {
96124
<div className="col-md-4">
97125
<select
98126
className="form-select mb-2"
99-
value={connectionCtx.currentUserObjectListName || "default"}
127+
value={
128+
connectionCtx.currentUserObjectListName ||
129+
"default" ||
130+
"personal"
131+
}
100132
onChange={selectListHandler}
101133
>
102134
<option value="default">{t("cGoToListdefault")}</option>
135+
<option value="personal">{t("cGoToListpersonal")}</option>
103136
{objectListsNames.map((list, index) => (
104137
<option key={index} value={list}>
105138
{list}
@@ -115,12 +148,14 @@ export default function GotoUserLists(props: PropType) {
115148
>
116149
{t("cGoToUserListNewList")}
117150
</button>
118-
<button
119-
className="btn btn-more03 me-2 mb-2"
120-
onClick={deleteListModalHandle}
121-
>
122-
{t("cGoToUserListDeleteList")}
123-
</button>
151+
{!selectPersonalList && (
152+
<button
153+
className="btn btn-more03 me-2 mb-2"
154+
onClick={deleteListModalHandle}
155+
>
156+
{t("cGoToUserListDeleteList")}
157+
</button>
158+
)}
124159
</div>
125160
</div>
126161

@@ -130,6 +165,9 @@ export default function GotoUserLists(props: PropType) {
130165
objects={objectLists[connectionCtx.currentUserObjectListName]}
131166
objectFavoriteNames={objectFavoriteNames}
132167
setObjectFavoriteNames={setObjectFavoriteNames}
168+
objectPersonalList={objectPersonalList}
169+
setObjectPersonalList={setObjectPersonalList}
170+
isInObjectPersonalList={selectPersonalList}
133171
setModule={setModule}
134172
setErrors={setErrors}
135173
setSuccess={setSuccess}

src/components/ImportObservationListModal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export default function ImportObjectListModal(props: PropTypes) {
101101
} as ObjectTelescopius;
102102
})
103103
);
104+
console.log("saveObjectListsDb", JSON.stringify(cloneObjectLists));
104105
saveObjectListsDb(JSON.stringify(cloneObjectLists));
105106
setObjectLists(cloneObjectLists);
106107

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import type { FormEvent, Dispatch, SetStateAction } from "react";
2+
import Modal from "react-bootstrap/Modal";
3+
import { useState, useEffect } from "react";
4+
5+
import { useTranslation } from "react-i18next";
6+
import i18n from "@/i18n";
7+
8+
import { AstroObject } from "@/types";
9+
import { saveObjectListsByNameDb } from "@/db/db_utils";
10+
11+
type PropTypes = {
12+
objectName: string;
13+
objectPersonalList: AstroObject[];
14+
setObjectPersonalList: Dispatch<SetStateAction<AstroObject[]>>;
15+
setIsInPersonalList: Dispatch<SetStateAction<boolean>>;
16+
showModal: boolean;
17+
setShowModal: Dispatch<SetStateAction<boolean>>;
18+
};
19+
20+
export default function RemoveFromPersonalLibrary(props: PropTypes) {
21+
const {
22+
objectName,
23+
objectPersonalList,
24+
setObjectPersonalList,
25+
setIsInPersonalList,
26+
showModal,
27+
setShowModal,
28+
} = props;
29+
30+
function handleCloseModal() {
31+
setShowModal(false);
32+
}
33+
34+
function removeAstroObject(
35+
list: AstroObject[],
36+
nameToRemove: string
37+
): AstroObject[] {
38+
return list.filter((obj) => obj.displayName !== nameToRemove);
39+
}
40+
41+
function removeObjectHandler(e: FormEvent<HTMLFormElement>) {
42+
e.preventDefault();
43+
44+
console.log("Before:", objectPersonalList);
45+
const updatedPersonalList = removeAstroObject(
46+
objectPersonalList,
47+
objectName
48+
);
49+
console.log("After:", updatedPersonalList);
50+
saveObjectListsByNameDb("personal", JSON.stringify(updatedPersonalList));
51+
setObjectPersonalList(updatedPersonalList);
52+
setIsInPersonalList(false);
53+
54+
// close modal
55+
setShowModal(false);
56+
}
57+
58+
const { t } = useTranslation();
59+
// eslint-disable-next-line no-unused-vars
60+
const [selectedLanguage, setSelectedLanguage] = useState<string>("en");
61+
62+
useEffect(() => {
63+
const storedLanguage = localStorage.getItem("language");
64+
if (storedLanguage) {
65+
setSelectedLanguage(storedLanguage);
66+
i18n.changeLanguage(storedLanguage);
67+
}
68+
}, []);
69+
70+
return (
71+
<Modal show={showModal} onHide={handleCloseModal}>
72+
<Modal.Header closeButton>
73+
<Modal.Title>{t("cRemoveFromPersonalListTitle")}</Modal.Title>
74+
</Modal.Header>
75+
76+
<Modal.Body>
77+
<form onSubmit={removeObjectHandler}>
78+
<p className="mb-3">{t("cRemoveFromPersonalListConfirm")}?</p>
79+
80+
<button type="submit" className="btn btn-more03 me-2 mb-2">
81+
{t("cRemoveFromPersonalListButton")}
82+
</button>
83+
</form>
84+
</Modal.Body>
85+
</Modal>
86+
);
87+
}

0 commit comments

Comments
 (0)