mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
adjusted station information modals, start new chat easily via heard stations
This commit is contained in:
parent
1cf316cb17
commit
1750565b71
|
@ -6,7 +6,9 @@ import chat_conversations from "./chat_conversations.vue";
|
|||
import chat_messages from "./chat_messages.vue";
|
||||
import chat_new_message from "./chat_new_message.vue";
|
||||
|
||||
import { getStationInfo } from "./../js/api";
|
||||
import { getStationInfoByCallsign } from "./../js/stationHandler";
|
||||
|
||||
|
||||
|
||||
import { setActivePinia } from "pinia";
|
||||
import pinia from "../store/index";
|
||||
|
@ -118,67 +120,10 @@ watch(
|
|||
},
|
||||
);
|
||||
|
||||
const stationInfo = ref({
|
||||
callsign: "N/A", // Default value for callsign
|
||||
location: {
|
||||
gridsquare: "N/A", // Default value for gridsquare
|
||||
},
|
||||
});
|
||||
|
||||
async function getStationInfoByCallsign() {
|
||||
try {
|
||||
const data = await getStationInfo(chat.selectedCallsign);
|
||||
stationInfo.value = {
|
||||
callsign: data.callsign || "N/A", // Default if not present
|
||||
location: {
|
||||
gridsquare: data.location?.gridsquare || "N/A", // Default if not present
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error fetching station info:", error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Station Info Modal -->
|
||||
<div
|
||||
class="modal fade"
|
||||
ref="modalEle"
|
||||
id="dxStationInfoModal"
|
||||
tabindex="-1"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="p-0 m-0">{{ stationInfo.callsign }}</h4>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
<strong>Location:</strong> {{ stationInfo.location.gridsquare }}
|
||||
</p>
|
||||
<p><strong>Details:</strong> {{ stationInfo.details }}</p>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary"
|
||||
data-bs-dismiss="modal"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid d-flex p-0">
|
||||
<!-- Chat Conversations -->
|
||||
|
@ -202,7 +147,8 @@ async function getStationInfoByCallsign() {
|
|||
class="btn btn-sm btn-outline-secondary ms-2 border-0"
|
||||
data-bs-target="#dxStationInfoModal"
|
||||
data-bs-toggle="modal"
|
||||
@click="getStationInfoByCallsign()"
|
||||
@click="getStationInfoByCallsign(chat.selectedCallsign)"
|
||||
disabled
|
||||
>
|
||||
<h4 class="p-0 m-0">{{ chat.selectedCallsign }}</h4>
|
||||
</button>
|
||||
|
|
|
@ -35,6 +35,13 @@ function newChat() {
|
|||
if (callsign === "") return;
|
||||
this.newChatCall.value = "";
|
||||
}
|
||||
function startNewChat(){
|
||||
chat.newChatCallsign = "";
|
||||
chat.newChatMessage = "Hi there! Nice to meet you!"
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -43,6 +50,7 @@ function newChat() {
|
|||
class="btn btn-outline-primary w-100"
|
||||
data-bs-target="#newChatModal"
|
||||
data-bs-toggle="modal"
|
||||
@click="startNewChat()"
|
||||
>
|
||||
<i class="bi bi-pencil-square"> Start a new chat</i>
|
||||
</button>
|
||||
|
|
|
@ -11,6 +11,12 @@ import { settingsStore as settings } from "../../store/settingsStore.js";
|
|||
import { useStateStore } from "../../store/stateStore.js";
|
||||
const state = useStateStore(pinia);
|
||||
|
||||
import { useChatStore } from "../../store/chatStore.js";
|
||||
const chat = useChatStore(pinia);
|
||||
|
||||
import { getStationInfoByCallsign } from "./../../js/stationHandler";
|
||||
|
||||
|
||||
function getDateTime(timestampRaw) {
|
||||
var datetime = new Date(timestampRaw * 1000).toLocaleString(
|
||||
navigator.language,
|
||||
|
@ -61,6 +67,12 @@ function getActivityInfo(activityType) {
|
|||
return { iconClass: "", description: activityType };
|
||||
}
|
||||
}
|
||||
|
||||
function startNewChat(callsign){
|
||||
chat.newChatCallsign = callsign;
|
||||
chat.newChatMessage = "Hi there! Nice to meet you!"
|
||||
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="card h-100">
|
||||
|
@ -99,7 +111,26 @@ function getActivityInfo(activityType) {
|
|||
</td>
|
||||
<td>{{ item.frequency / 1000 }} kHz</td>
|
||||
<td>
|
||||
{{ item.origin }}
|
||||
|
||||
<button
|
||||
class="btn btn-sm btn-outline-secondary ms-2 border-0"
|
||||
data-bs-target="#dxStationInfoModal"
|
||||
data-bs-toggle="modal"
|
||||
@click="getStationInfoByCallsign(item.origin)"
|
||||
disabled
|
||||
>
|
||||
<h6 class="p-0 m-0">{{ item.origin }}</h6>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="btn btn-sm border-0 btn-outline-primary"
|
||||
data-bs-target="#newChatModal"
|
||||
data-bs-toggle="modal"
|
||||
@click="startNewChat(item.origin)"
|
||||
|
||||
>
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
{{ item.gridsquare }}
|
||||
|
|
|
@ -10,13 +10,19 @@ setActivePinia(pinia);
|
|||
import { useChatStore } from "../store/chatStore.js";
|
||||
const chat = useChatStore(pinia);
|
||||
|
||||
import { useStationStore } from "../store/stationStore.js";
|
||||
const station = useStationStore(pinia);
|
||||
import { useStateStore } from "../store/stateStore.js";
|
||||
const state = useStateStore(pinia);
|
||||
|
||||
import { getStationInfoByCallsign, setStationInfoByCallsign } from "../js/stationHandler.js";
|
||||
|
||||
|
||||
|
||||
import { settingsStore } from "../store/settingsStore.js";
|
||||
|
||||
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
|
||||
import { sendModemTestFrame, setStationInfo, getStationInfo } from "../js/api";
|
||||
import { sendModemTestFrame } from "../js/api";
|
||||
import main_startup_check from "./main_startup_check.vue";
|
||||
import { newMessage, deleteCallsignFromDB } from "../js/messagesHandler.ts";
|
||||
|
||||
|
@ -118,6 +124,9 @@ const transmissionSpeedChartDataMessageInfo = computed(() => ({
|
|||
],
|
||||
}));
|
||||
|
||||
|
||||
|
||||
/*
|
||||
const stationInfoData = ref({
|
||||
name: "",
|
||||
city: "",
|
||||
|
@ -137,53 +146,89 @@ const stationInfoData = ref({
|
|||
},
|
||||
comments: "",
|
||||
});
|
||||
*/
|
||||
|
||||
// Function to handle updates and save changes
|
||||
function updateStationInfo() {
|
||||
console.log("Updating station info:", stationInfoData.value);
|
||||
let mycall = settingsStore.remote.STATION.mycall;
|
||||
let myssid = settingsStore.remote.STATION.myssid;
|
||||
let fullCall = `${mycall}-${myssid}`;
|
||||
setStationInfo(fullCall, stationInfoData.value);
|
||||
console.log("Updating station info:", fullCall);
|
||||
|
||||
setStationInfoByCallsign(fullCall, station.stationInfo.value);
|
||||
}
|
||||
|
||||
// Fixme: this is a dirty hack. Can we make this more VueJS like?
|
||||
onMounted(() => {
|
||||
const modalElement = document.getElementById("stationInfoModal");
|
||||
modalElement.addEventListener("show.bs.modal", fetchStationInfo);
|
||||
modalElement.addEventListener("show.bs.modal", fetchMyStationInfo);
|
||||
});
|
||||
|
||||
async function fetchStationInfo() {
|
||||
|
||||
function fetchMyStationInfo(){
|
||||
|
||||
let mycall = settingsStore.remote.STATION.mycall;
|
||||
let myssid = settingsStore.remote.STATION.myssid;
|
||||
let fullCall = `${mycall}-${myssid}`;
|
||||
let result = await getStationInfo(fullCall);
|
||||
let info = result.info;
|
||||
stationInfoData.value = {
|
||||
name: info.name || "",
|
||||
city: info.city || "",
|
||||
age: info.age || "",
|
||||
radio: info.radio || "",
|
||||
antenna: info.antenna || "",
|
||||
email: info.email || "",
|
||||
website: info.website || "",
|
||||
socialMedia: {
|
||||
facebook: info.socialMedia.facebook || "",
|
||||
"twitter-x": info.socialMedia["twitter-x"] || "",
|
||||
mastodon: info.socialMedia.mastodon || "",
|
||||
instagram: info.socialMedia.instagram || "",
|
||||
linkedin: info.socialMedia.linkedin || "",
|
||||
youtube: info.socialMedia.youtube || "",
|
||||
tiktok: info.socialMedia.tiktok || "",
|
||||
},
|
||||
comments: info.comments || "",
|
||||
};
|
||||
getStationInfoByCallsign(fullCall)
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main_startup_check />
|
||||
|
||||
<!-- Station Info Modal -->
|
||||
<div
|
||||
class="modal fade"
|
||||
ref="modalEle"
|
||||
id="dxStationInfoModal"
|
||||
tabindex="-1"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
|
||||
<h4 class="p-0 m-0">{{ station.stationInfo.callsign }}</h4>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="alert alert-primary" role="alert">
|
||||
<strong> Please note:</strong> This is a preview to show you the
|
||||
direction, FreeDATA is going somewhen. For now you can save only
|
||||
your personal data, so we can optimize and improve the database. In
|
||||
future this data can be requested by a remote station.
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<li v-for="(value, key) in station.stationInfo.info" :key="key">
|
||||
<strong>{{ key }}:</strong> {{ value }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary"
|
||||
data-bs-dismiss="modal"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- updater release notes-->
|
||||
<div
|
||||
class="modal fade"
|
||||
|
@ -408,7 +453,9 @@ async function fetchStationInfo() {
|
|||
<br />
|
||||
2. Enter a first message
|
||||
<br />
|
||||
3. Pressing "START NEW CHAT"
|
||||
3. Click "START NEW CHAT"
|
||||
<br />
|
||||
4. Check the chat tab on left side for messages
|
||||
</div>
|
||||
|
||||
<div class="form-floating mb-3">
|
||||
|
@ -1421,7 +1468,7 @@ async function fetchStationInfo() {
|
|||
type="text"
|
||||
class="form-control"
|
||||
placeholder="Name"
|
||||
v-model="stationInfoData.name"
|
||||
v-model="station.stationInfo.info.name"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -1434,7 +1481,7 @@ async function fetchStationInfo() {
|
|||
type="text"
|
||||
class="form-control"
|
||||
placeholder="City"
|
||||
v-model="stationInfoData.city"
|
||||
v-model="station.stationInfo.info.city"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -1447,7 +1494,7 @@ async function fetchStationInfo() {
|
|||
type="text"
|
||||
class="form-control"
|
||||
placeholder="Age"
|
||||
v-model="stationInfoData.age"
|
||||
v-model="station.stationInfo.info.age"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -1460,7 +1507,7 @@ async function fetchStationInfo() {
|
|||
type="text"
|
||||
class="form-control"
|
||||
placeholder="Radio"
|
||||
v-model="stationInfoData.radio"
|
||||
v-model="station.stationInfo.info.radio"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -1473,7 +1520,7 @@ async function fetchStationInfo() {
|
|||
type="text"
|
||||
class="form-control"
|
||||
placeholder="Antenna"
|
||||
v-model="stationInfoData.antenna"
|
||||
v-model="station.stationInfo.info.antenna"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -1484,7 +1531,7 @@ async function fetchStationInfo() {
|
|||
type="url"
|
||||
class="form-control"
|
||||
placeholder="Website"
|
||||
v-model="stationInfoData.website"
|
||||
v-model="station.stationInfo.info.website"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -1497,13 +1544,13 @@ async function fetchStationInfo() {
|
|||
type="email"
|
||||
class="form-control"
|
||||
placeholder="Email"
|
||||
v-model="stationInfoData.email"
|
||||
v-model="station.stationInfo.info.email"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Social Media Inputs -->
|
||||
<div class="mb-3">
|
||||
<div v-for="(url, platform) in stationInfoData.socialMedia">
|
||||
<div v-for="(url, platform) in station.stationInfo.info.socialMedia">
|
||||
<div class="input-group mb-1" :key="platform">
|
||||
<span class="input-group-text"
|
||||
><i :class="`bi bi-${platform}`"></i
|
||||
|
@ -1512,7 +1559,7 @@ async function fetchStationInfo() {
|
|||
type="url"
|
||||
class="form-control"
|
||||
:placeholder="`${platform.charAt(0).toUpperCase() + platform.slice(1)} URL`"
|
||||
v-model="stationInfoData.socialMedia[platform]"
|
||||
v-model="station.stationInfo.info.socialMedia[platform]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1526,7 +1573,7 @@ async function fetchStationInfo() {
|
|||
<textarea
|
||||
class="form-control"
|
||||
rows="3"
|
||||
v-model="stationInfoData.comments"
|
||||
v-model="station.stationInfo.info.comments"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
|
67
freedata_gui/src/js/stationHandler.ts
Normal file
67
freedata_gui/src/js/stationHandler.ts
Normal file
|
@ -0,0 +1,67 @@
|
|||
import { useStationStore } from "../store/stationStore.js";
|
||||
const station = useStationStore();
|
||||
|
||||
import { getStationInfo, setStationInfo } from "../js/api";
|
||||
|
||||
export async function getStationInfoByCallsign(callsign) {
|
||||
|
||||
try {
|
||||
const result = await getStationInfo(callsign);
|
||||
console.log(result)
|
||||
|
||||
station.stationInfo.callsign = result.callsign || "N/A";
|
||||
station.stationInfo.location.gridsquare = result.location?.gridsquare || "N/A";
|
||||
// Check if info is null and assign default values if it is
|
||||
if (result.info === null) {
|
||||
station.stationInfo.value.info = {
|
||||
name: "",
|
||||
city: "",
|
||||
age: "",
|
||||
radio: "",
|
||||
antenna: "",
|
||||
email: "",
|
||||
website: "",
|
||||
socialMedia: {
|
||||
facebook: "",
|
||||
"twitter-x": "",
|
||||
mastodon: "",
|
||||
instagram: "",
|
||||
linkedin: "",
|
||||
youtube: "",
|
||||
tiktok: "",
|
||||
},
|
||||
comments: "",
|
||||
};
|
||||
} else {
|
||||
station.stationInfo.info = {
|
||||
name: result.info.name || "",
|
||||
city: result.info.city || "",
|
||||
age: result.info.age || "",
|
||||
radio: result.info.radio || "",
|
||||
antenna: result.info.antenna || "",
|
||||
email: result.info.email || "",
|
||||
website: result.info.website || "",
|
||||
socialMedia: {
|
||||
facebook: result.info.socialMedia.facebook || "",
|
||||
"twitter-x": result.info.socialMedia["twitter-x"] || "",
|
||||
mastodon: result.info.socialMedia.mastodon || "",
|
||||
instagram: result.info.socialMedia.instagram || "",
|
||||
linkedin: result.info.socialMedia.linkedin || "",
|
||||
youtube: result.info.socialMedia.youtube || "",
|
||||
tiktok: result.info.socialMedia.tiktok || "",
|
||||
},
|
||||
comments: result.info.comments || "",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error fetching station info:", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function setStationInfoByCallsign(callsign){
|
||||
console.log(station.stationInfo)
|
||||
setStationInfo(callsign, station.stationInfo)
|
||||
}
|
33
freedata_gui/src/store/stationStore.js
Normal file
33
freedata_gui/src/store/stationStore.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
import * as bootstrap from "bootstrap";
|
||||
export const useStationStore = defineStore("stationStore", () => {
|
||||
const stationInfo = ref({
|
||||
callsign: "N/A", // Default value for callsign
|
||||
location: {
|
||||
gridsquare: "N/A", // Default value for gridsquare
|
||||
},
|
||||
info: {
|
||||
name: "",
|
||||
city: "",
|
||||
age: "",
|
||||
radio: "",
|
||||
antenna: "",
|
||||
email: "",
|
||||
website: "",
|
||||
socialMedia: {
|
||||
facebook: "",
|
||||
"twitter-x": "", // Use twitter-x to correspond to the Twitter X icon
|
||||
mastodon: "",
|
||||
instagram: "",
|
||||
linkedin: "",
|
||||
youtube: "",
|
||||
tiktok: "",
|
||||
},
|
||||
comments: "",
|
||||
}
|
||||
});
|
||||
return{
|
||||
stationInfo
|
||||
}
|
||||
});
|
|
@ -33,7 +33,7 @@ class DatabaseManagerStations(DatabaseManager):
|
|||
finally:
|
||||
session.remove()
|
||||
|
||||
def update_station(self, callsign, new_info):
|
||||
def update_station_info(self, callsign, new_info):
|
||||
"""
|
||||
Updates the information of a station identified by its callsign.
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ def set_config():
|
|||
else:
|
||||
print(f"Config file '{config_file}' not found. Exiting.")
|
||||
sys.exit(1)
|
||||
|
||||
return config_file
|
||||
|
||||
|
||||
|
@ -80,7 +79,7 @@ def validate(req, param, validator, isRequired = True):
|
|||
api_abort(f"Value of '{param}' is invalid.", 400)
|
||||
|
||||
# Takes a transmit command and puts it in the transmit command queue
|
||||
def enqueue_tx_command(cmd_class, params = {}):
|
||||
def enqueue_tx_command(cmd_class, params={}):
|
||||
try:
|
||||
command = cmd_class(app.config_manager.read(), app.state_manager, app.event_manager, params)
|
||||
app.logger.info(f"Command {command.get_name()} running...")
|
||||
|
@ -323,8 +322,8 @@ def get_set_station_info_by_callsign(callsign):
|
|||
if request.method in ['GET']:
|
||||
station = DatabaseManagerStations(app.event_manager).get_station(callsign)
|
||||
return api_response(station)
|
||||
elif request.method in ['POST']:
|
||||
result = DatabaseManagerStations(app.event_manager).update_station(callsign, new_info=request.json)
|
||||
elif request.method in ['POST'] and "info" in request.json:
|
||||
result = DatabaseManagerStations(app.event_manager).update_station_info(callsign, new_info=request.json["info"])
|
||||
return api_response(result)
|
||||
else:
|
||||
api_abort('Error using endpoint...', 500)
|
||||
|
|
Loading…
Reference in a new issue