feat(dvk): delete a message — recording and label together
A deleted message is a free slot, per its operator; keeping the label made it look half-deleted.
This commit is contained in:
@@ -10300,6 +10300,22 @@ func (a *App) GetDVKMessages() []DVKMessage {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DVKDelete removes a slot's recording AND its label — a deleted message is a
|
||||||
|
// free slot, per its operator.
|
||||||
|
func (a *App) DVKDelete(slot int) error {
|
||||||
|
if slot < 1 || slot > dvkSlots {
|
||||||
|
return fmt.Errorf("bad slot")
|
||||||
|
}
|
||||||
|
if err := os.Remove(a.dvkPath(slot)); err != nil && !os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("delete message %d: %w", slot, err)
|
||||||
|
}
|
||||||
|
if a.settings != nil {
|
||||||
|
_ = a.settings.Set(a.ctx, dvkLabelKey(slot), "")
|
||||||
|
}
|
||||||
|
applog.Printf("dvk: message F%d deleted (label cleared)", slot)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetDVKLabel renames a voice-keyer slot.
|
// SetDVKLabel renames a voice-keyer slot.
|
||||||
func (a *App) SetDVKLabel(slot int, label string) error {
|
func (a *App) SetDVKLabel(slot int, label string) error {
|
||||||
if a.settings == nil {
|
if a.settings == nil {
|
||||||
|
|||||||
+4
-2
@@ -6,13 +6,15 @@
|
|||||||
"KPA500: the amplifier no longer switches itself off and commands respond instantly. A command this model does not know (the KPA1500’s ATU poll) was tearing the link down every cycle, and each reconnect toggled the serial control lines — which are the KPA500’s power switch. The lines are now held steady, silence is not treated as a dead link, and the baud is picked from a list.",
|
"KPA500: the amplifier no longer switches itself off and commands respond instantly. A command this model does not know (the KPA1500’s ATU poll) was tearing the link down every cycle, and each reconnect toggled the serial control lines — which are the KPA500’s power switch. The lines are now held steady, silence is not treated as a dead link, and the baud is picked from a list.",
|
||||||
"FT decodes: within a period, decodes are listed in arrival order — mirroring the decoder’s own window — instead of strongest-first.",
|
"FT decodes: within a period, decodes are listed in arrival order — mirroring the decoder’s own window — instead of strongest-first.",
|
||||||
"Voice keyer: twelve message slots (F1–F12) instead of six.",
|
"Voice keyer: twelve message slots (F1–F12) instead of six.",
|
||||||
"Preferences open smoothly on a busy station: while the dialog is open, cluster spots, FT decodes and CAT snapshots queue quietly instead of repainting the whole window behind it — everything catches up the moment it closes."
|
"Preferences open smoothly on a busy station: while the dialog is open, cluster spots, FT decodes and CAT snapshots queue quietly instead of repainting the whole window behind it — everything catches up the moment it closes.",
|
||||||
|
"Voice keyer: a delete button per message — removes the recording and clears the label."
|
||||||
],
|
],
|
||||||
"fr": [
|
"fr": [
|
||||||
"KPA500 : l’ampli ne s’éteint plus tout seul et les commandes répondent instantanément. Une commande inconnue de ce modèle (le poll ATU du KPA1500) détruisait le lien à chaque cycle, et chaque reconnexion basculait les lignes de contrôle série — qui sont l’interrupteur du KPA500. Les lignes sont désormais tenues stables, le silence n’est plus traité comme un lien mort, et le baud se choisit dans une liste.",
|
"KPA500 : l’ampli ne s’éteint plus tout seul et les commandes répondent instantanément. Une commande inconnue de ce modèle (le poll ATU du KPA1500) détruisait le lien à chaque cycle, et chaque reconnexion basculait les lignes de contrôle série — qui sont l’interrupteur du KPA500. Les lignes sont désormais tenues stables, le silence n’est plus traité comme un lien mort, et le baud se choisit dans une liste.",
|
||||||
"FT decodes : dans une période, les décodages sont listés dans l’ordre d’arrivée — comme la fenêtre du décodeur — au lieu du plus fort d’abord.",
|
"FT decodes : dans une période, les décodages sont listés dans l’ordre d’arrivée — comme la fenêtre du décodeur — au lieu du plus fort d’abord.",
|
||||||
"Manipulateur vocal : douze messages (F1–F12) au lieu de six.",
|
"Manipulateur vocal : douze messages (F1–F12) au lieu de six.",
|
||||||
"Les Préférences restent fluides sur une station chargée : dialogue ouvert, les spots cluster, les décodages FT et les instantanés CAT patientent en file au lieu de repeindre toute la fenêtre derrière — tout se rattrape à la fermeture."
|
"Les Préférences restent fluides sur une station chargée : dialogue ouvert, les spots cluster, les décodages FT et les instantanés CAT patientent en file au lieu de repeindre toute la fenêtre derrière — tout se rattrape à la fermeture.",
|
||||||
|
"Manipulateur vocal : un bouton supprimer par message — efface l’enregistrement et le libellé."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
GetLookupSettings, SaveLookupSettings, ClearLookupCache, TestLookupProvider,
|
GetLookupSettings, SaveLookupSettings, ClearLookupCache, TestLookupProvider,
|
||||||
GetListsSettings, SaveListsSettings,
|
GetListsSettings, SaveListsSettings,
|
||||||
GetCATSettings, SaveCATSettings, GetRadios, SaveRadios, SetActiveRadio, ActiveRadioID, DiscoverFlexRadios,
|
GetCATSettings, SaveCATSettings, GetRadios, SaveRadios, SetActiveRadio, ActiveRadioID, DiscoverFlexRadios, DVKDelete,
|
||||||
GetAudioMonitorPref,
|
GetAudioMonitorPref,
|
||||||
ListProfiles, GetActiveProfile, SaveProfile, DeleteProfile, ActivateProfile, DuplicateProfile,
|
ListProfiles, GetActiveProfile, SaveProfile, DeleteProfile, ActivateProfile, DuplicateProfile,
|
||||||
GetRotators, SaveRotators, TestRotatorDevice, RotatorPark, RotatorStop,
|
GetRotators, SaveRotators, TestRotatorDevice, RotatorPark, RotatorStop,
|
||||||
@@ -7178,6 +7178,15 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
|
|||||||
>
|
>
|
||||||
{dvkStat.playing ? t('aud.stop') : t('aud.play')}
|
{dvkStat.playing ? t('aud.stop') : t('aud.play')}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline" size="sm" className="h-8 w-9 shrink-0 px-0 text-danger hover:text-danger"
|
||||||
|
title={t('aud.deleteMsg')}
|
||||||
|
disabled={!m.has_audio || dvkStat.recording || dvkStat.playing}
|
||||||
|
onClick={() => DVKDelete(m.slot).then(reloadDvk).catch((err) => setDvkErr(String(err?.message ?? err)))}
|
||||||
|
>
|
||||||
|
<Trash2 className="size-3.5" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -535,7 +535,7 @@ const en: Dict = {
|
|||||||
'aud.preroll': 'Pre-roll (seconds)', 'aud.format': 'File format', 'aud.wav': 'WAV (lossless, larger)', 'aud.mp3': 'MP3 (compressed, small)',
|
'aud.preroll': 'Pre-roll (seconds)', 'aud.format': 'File format', 'aud.wav': 'WAV (lossless, larger)', 'aud.mp3': 'MP3 (compressed, small)',
|
||||||
'aud.fromLevel': 'From Radio level', 'aud.txLevel': 'Voice keyer level', 'aud.txLevelHint': 'Level of the recorded messages sent to the radio. Raise it if your voice keyer is much quieter than your microphone; Play previews at this same level. If the radio transmits almost nothing, its modulation source is still the front microphone: on an FTDX10 set MENU → SSB MOD SOURCE to REAR (the USB input).', 'aud.micLevel': 'Mic level', 'aud.qsoPlayLevel': 'QSO playback level', 'aud.levelHint': 'If your voice is louder than the station, lower Mic level.',
|
'aud.fromLevel': 'From Radio level', 'aud.txLevel': 'Voice keyer level', 'aud.txLevelHint': 'Level of the recorded messages sent to the radio. Raise it if your voice keyer is much quieter than your microphone; Play previews at this same level. If the radio transmits almost nothing, its modulation source is still the front microphone: on an FTDX10 set MENU → SSB MOD SOURCE to REAR (the USB input).', 'aud.micLevel': 'Mic level', 'aud.qsoPlayLevel': 'QSO playback level', 'aud.levelHint': 'If your voice is louder than the station, lower Mic level.',
|
||||||
'aud.autoSend': 'Auto-send the recording to the station by e-mail when I log a QSO',
|
'aud.autoSend': 'Auto-send the recording to the station by e-mail when I log a QSO',
|
||||||
'aud.dvkTitle': 'Voice keyer messages (F1–F12)', 'aud.pttMethod': 'PTT method', 'aud.pttNone': 'None (VOX)', 'aud.pttCat': 'CAT (the radio link)', 'aud.pttRts': 'Serial RTS', 'aud.pttDtr': 'Serial DTR',
|
'aud.dvkTitle': 'Voice keyer messages (F1–F12)', 'aud.deleteMsg': 'Delete this message', 'aud.pttMethod': 'PTT method', 'aud.pttNone': 'None (VOX)', 'aud.pttCat': 'CAT (the radio link)', 'aud.pttRts': 'Serial RTS', 'aud.pttDtr': 'Serial DTR',
|
||||||
'aud.testPtt': 'Test PTT', 'aud.pttPort': 'PTT COM port', 'aud.pickPort': 'Pick a COM port', 'aud.selectPort': '— select —', 'aud.refresh': 'Refresh',
|
'aud.testPtt': 'Test PTT', 'aud.pttPort': 'PTT COM port', 'aud.pickPort': 'Pick a COM port', 'aud.selectPort': '— select —', 'aud.refresh': 'Refresh',
|
||||||
'aud.msgPlaceholder': 'Message {n} label (CQ, report, 73…)', 'aud.holdRec': '● Hold to rec', 'aud.recordingNow': '● Recording…', 'aud.play': '▶ Play', 'aud.stop': '■ Stop',
|
'aud.msgPlaceholder': 'Message {n} label (CQ, report, 73…)', 'aud.holdRec': '● Hold to rec', 'aud.recordingNow': '● Recording…', 'aud.play': '▶ Play', 'aud.stop': '■ Stop',
|
||||||
'aud.errPttTest': 'PTT test: ', 'aud.errRecord': 'Record: ', 'aud.errSave': 'Save: ', 'aud.errPlay': 'Play: ',
|
'aud.errPttTest': 'PTT test: ', 'aud.errRecord': 'Record: ', 'aud.errSave': 'Save: ', 'aud.errPlay': 'Play: ',
|
||||||
@@ -1037,7 +1037,7 @@ const fr: Dict = {
|
|||||||
'aud.preroll': 'Pré-enregistrement (secondes)', 'aud.format': 'Format de fichier', 'aud.wav': 'WAV (sans perte, plus volumineux)', 'aud.mp3': 'MP3 (compressé, léger)',
|
'aud.preroll': 'Pré-enregistrement (secondes)', 'aud.format': 'Format de fichier', 'aud.wav': 'WAV (sans perte, plus volumineux)', 'aud.mp3': 'MP3 (compressé, léger)',
|
||||||
'aud.fromLevel': 'Niveau depuis la radio', 'aud.txLevel': 'Niveau du voice keyer', 'aud.txLevelHint': "Niveau des messages enregistrés envoyés à la radio. Augmentez-le si votre voice keyer est bien plus faible que votre micro ; Lire fait entendre ce même niveau. Si la radio n'émet presque rien, c'est que sa source de modulation est restée le micro de façade : sur un FTDX10, réglez MENU → SSB MOD SOURCE sur REAR (l'entrée USB).", 'aud.micLevel': 'Niveau micro', 'aud.qsoPlayLevel': 'Niveau de relecture QSO', 'aud.levelHint': 'Si votre voix est plus forte que la station, baissez le niveau micro.',
|
'aud.fromLevel': 'Niveau depuis la radio', 'aud.txLevel': 'Niveau du voice keyer', 'aud.txLevelHint': "Niveau des messages enregistrés envoyés à la radio. Augmentez-le si votre voice keyer est bien plus faible que votre micro ; Lire fait entendre ce même niveau. Si la radio n'émet presque rien, c'est que sa source de modulation est restée le micro de façade : sur un FTDX10, réglez MENU → SSB MOD SOURCE sur REAR (l'entrée USB).", 'aud.micLevel': 'Niveau micro', 'aud.qsoPlayLevel': 'Niveau de relecture QSO', 'aud.levelHint': 'Si votre voix est plus forte que la station, baissez le niveau micro.',
|
||||||
'aud.autoSend': "Envoyer automatiquement l'enregistrement à la station par e-mail lorsque j'enregistre un QSO",
|
'aud.autoSend': "Envoyer automatiquement l'enregistrement à la station par e-mail lorsque j'enregistre un QSO",
|
||||||
'aud.dvkTitle': 'Messages du manipulateur vocal (F1–F12)', 'aud.pttMethod': 'Méthode PTT', 'aud.pttNone': 'Aucune (VOX)', 'aud.pttCat': 'CAT (la liaison radio)', 'aud.pttRts': 'RTS série', 'aud.pttDtr': 'DTR série',
|
'aud.dvkTitle': 'Messages du manipulateur vocal (F1–F12)', 'aud.deleteMsg': 'Supprimer ce message', 'aud.pttMethod': 'Méthode PTT', 'aud.pttNone': 'Aucune (VOX)', 'aud.pttCat': 'CAT (la liaison radio)', 'aud.pttRts': 'RTS série', 'aud.pttDtr': 'DTR série',
|
||||||
'aud.testPtt': 'Tester le PTT', 'aud.pttPort': 'Port COM du PTT', 'aud.pickPort': 'Choisir un port COM', 'aud.selectPort': '— choisir —', 'aud.refresh': 'Actualiser',
|
'aud.testPtt': 'Tester le PTT', 'aud.pttPort': 'Port COM du PTT', 'aud.pickPort': 'Choisir un port COM', 'aud.selectPort': '— choisir —', 'aud.refresh': 'Actualiser',
|
||||||
'aud.msgPlaceholder': 'Libellé du message {n} (CQ, report, 73…)', 'aud.holdRec': '● Maintenir pour enreg.', 'aud.recordingNow': '● Enregistrement…', 'aud.play': '▶ Lire', 'aud.stop': '■ Arrêter',
|
'aud.msgPlaceholder': 'Libellé du message {n} (CQ, report, 73…)', 'aud.holdRec': '● Maintenir pour enreg.', 'aud.recordingNow': '● Enregistrement…', 'aud.play': '▶ Lire', 'aud.stop': '■ Arrêter',
|
||||||
'aud.errPttTest': 'Test PTT : ', 'aud.errRecord': 'Enregistrement : ', 'aud.errSave': 'Sauvegarde : ', 'aud.errPlay': 'Lecture : ',
|
'aud.errPttTest': 'Test PTT : ', 'aud.errRecord': 'Enregistrement : ', 'aud.errSave': 'Sauvegarde : ', 'aud.errPlay': 'Lecture : ',
|
||||||
|
|||||||
Vendored
+2
@@ -160,6 +160,8 @@ export function CreateDatabase(arg1:string):Promise<void>;
|
|||||||
|
|
||||||
export function DVKCancelRecord():Promise<void>;
|
export function DVKCancelRecord():Promise<void>;
|
||||||
|
|
||||||
|
export function DVKDelete(arg1:number):Promise<void>;
|
||||||
|
|
||||||
export function DVKPlay(arg1:number):Promise<void>;
|
export function DVKPlay(arg1:number):Promise<void>;
|
||||||
|
|
||||||
export function DVKPreview(arg1:number):Promise<void>;
|
export function DVKPreview(arg1:number):Promise<void>;
|
||||||
|
|||||||
@@ -258,6 +258,10 @@ export function DVKCancelRecord() {
|
|||||||
return window['go']['main']['App']['DVKCancelRecord']();
|
return window['go']['main']['App']['DVKCancelRecord']();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function DVKDelete(arg1) {
|
||||||
|
return window['go']['main']['App']['DVKDelete'](arg1);
|
||||||
|
}
|
||||||
|
|
||||||
export function DVKPlay(arg1) {
|
export function DVKPlay(arg1) {
|
||||||
return window['go']['main']['App']['DVKPlay'](arg1);
|
return window['go']['main']['App']['DVKPlay'](arg1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user