Add clear logs, use more menu dialog

This commit is contained in:
advplyr 2025-04-20 10:32:52 -05:00
parent 2000534e37
commit 74758c7762
5 changed files with 71 additions and 15 deletions

View file

@ -301,4 +301,7 @@ class DbManager {
} }
return logs return logs
} }
fun removeAllLogs() {
Paper.book("log").destroy()
}
} }

View file

@ -58,4 +58,10 @@ class AbsLogger : Plugin() {
val absLogs = DeviceManager.dbManager.getAllLogs() val absLogs = DeviceManager.dbManager.getAllLogs()
call.resolve(JSObject(jacksonMapper.writeValueAsString(AbsLogList(absLogs)))) call.resolve(JSObject(jacksonMapper.writeValueAsString(AbsLogList(absLogs))))
} }
@PluginMethod
fun clearLogs(call: PluginCall) {
DeviceManager.dbManager.removeAllLogs()
call.resolve()
}
} }

View file

@ -5,11 +5,12 @@
<ui-icon-btn outlined borderless :icon="isCopied ? 'check' : 'content_copy'" @click="copyToClipboard" /> <ui-icon-btn outlined borderless :icon="isCopied ? 'check' : 'content_copy'" @click="copyToClipboard" />
<ui-icon-btn outlined borderless icon="share" @click="shareLogs" /> <ui-icon-btn outlined borderless icon="share" @click="shareLogs" />
<div class="flex-grow"></div> <div class="flex-grow"></div>
<ui-btn class="h-9" :padding-y="1" :padding-x="4" @click="toggleMaskServerAddress"> <ui-icon-btn outlined borderless icon="more_vert" @click="showDialog = true" />
{{ maskServerAddress ? $strings.ButtonUnmaskServerAddress : $strings.ButtonMaskServerAddress }}
</ui-btn>
</div> </div>
<div class="w-full h-[calc(100%-40px)] overflow-y-auto relative" ref="logContainer"> <div class="w-full h-[calc(100%-40px)] overflow-y-auto relative" ref="logContainer">
<div v-if="!logs.length && !isLoading" class="flex items-center justify-center h-32">
<p class="text-gray-400">{{ $strings.MessageNoLogs }}</p>
</div>
<div v-if="hasScrolled" class="sticky top-0 left-0 w-full h-10 bg-gradient-to-t from-transparent to-bg z-10 pointer-events-none"></div> <div v-if="hasScrolled" class="sticky top-0 left-0 w-full h-10 bg-gradient-to-t from-transparent to-bg z-10 pointer-events-none"></div>
<div v-for="log in logs" :key="log.id" class="py-1"> <div v-for="log in logs" :key="log.id" class="py-1">
@ -20,6 +21,8 @@
<div class="text-xs">{{ maskServerAddress ? log.maskedMessage : log.message }}</div> <div class="text-xs">{{ maskServerAddress ? log.maskedMessage : log.message }}</div>
</div> </div>
</div> </div>
<modals-dialog v-model="showDialog" :items="dialogItems" @action="dialogAction" />
</div> </div>
</template> </template>
<script> <script>
@ -30,17 +33,46 @@ export default {
data() { data() {
return { return {
logs: [], logs: [],
isLoading: true,
isCopied: false, isCopied: false,
hasScrolled: false, hasScrolled: false,
maskServerAddress: true maskServerAddress: true,
showDialog: false
}
},
computed: {
dialogItems() {
return [
{
text: this.maskServerAddress ? this.$strings.ButtonUnmaskServerAddress : this.$strings.ButtonMaskServerAddress,
value: 'toggle-mask-server-address',
icon: this.maskServerAddress ? 'remove_moderator' : 'shield'
},
{
text: this.$strings.ButtonClearLogs,
value: 'clear-logs',
icon: 'delete'
}
]
} }
}, },
computed: {},
methods: { methods: {
async dialogAction(action) {
await this.$hapticsImpact()
if (action === 'clear-logs') {
await AbsLogger.clearLogs()
this.logs = []
} else if (action === 'toggle-mask-server-address') {
this.maskServerAddress = !this.maskServerAddress
}
this.showDialog = false
},
toggleMaskServerAddress() { toggleMaskServerAddress() {
this.maskServerAddress = !this.maskServerAddress this.maskServerAddress = !this.maskServerAddress
}, },
copyToClipboard() { async copyToClipboard() {
await this.$hapticsImpact()
this.$copyToClipboard(this.getLogsString()).then(() => { this.$copyToClipboard(this.getLogsString()).then(() => {
this.isCopied = true this.isCopied = true
setTimeout(() => { setTimeout(() => {
@ -76,7 +108,8 @@ export default {
}) })
.join('\n') .join('\n')
}, },
shareLogs() { async shareLogs() {
await this.$hapticsImpact()
// Share .txt file with logs // Share .txt file with logs
const base64Data = Buffer.from(this.getLogsString()).toString('base64') const base64Data = Buffer.from(this.getLogsString()).toString('base64')
@ -99,16 +132,24 @@ export default {
return message.replace(/(https?:\/\/)\S+/g, '$1[SERVER_ADDRESS]') return message.replace(/(https?:\/\/)\S+/g, '$1[SERVER_ADDRESS]')
}, },
loadLogs() { loadLogs() {
AbsLogger.getAllLogs().then((logData) => { this.isLoading = true
const logs = logData.value || [] AbsLogger.getAllLogs()
this.logs = logs.map((log) => { .then((logData) => {
log.maskedMessage = this.maskLogMessage(log.message) const logs = logData.value || []
return log this.logs = logs.map((log) => {
log.maskedMessage = this.maskLogMessage(log.message)
return log
})
this.$nextTick(() => {
this.scrollToBottom()
})
this.isLoading = false
}) })
this.$nextTick(() => { .catch((error) => {
this.scrollToBottom() this.isLoading = false
console.error('Failed to load logs', error)
this.$toast.error('Failed to load logs: ' + error.message)
}) })
})
} }
}, },
mounted() { mounted() {

View file

@ -35,6 +35,10 @@ class AbsLoggerWeb extends WebPlugin {
value: this.logs value: this.logs
} }
} }
async clearLogs() {
this.logs = []
}
} }
const AbsLogger = registerPlugin('AbsLogger', { const AbsLogger = registerPlugin('AbsLogger', {

View file

@ -6,6 +6,7 @@
"ButtonCancel": "Cancel", "ButtonCancel": "Cancel",
"ButtonCancelTimer": "Cancel Timer", "ButtonCancelTimer": "Cancel Timer",
"ButtonClearFilter": "Clear Filter", "ButtonClearFilter": "Clear Filter",
"ButtonClearLogs": "Clear Logs",
"ButtonCloseFeed": "Close Feed", "ButtonCloseFeed": "Close Feed",
"ButtonCollections": "Collections", "ButtonCollections": "Collections",
"ButtonConnect": "Connect", "ButtonConnect": "Connect",
@ -313,6 +314,7 @@
"MessageNoItems": "No Items", "MessageNoItems": "No Items",
"MessageNoItemsFound": "No items found", "MessageNoItemsFound": "No items found",
"MessageNoListeningSessions": "No Listening Sessions", "MessageNoListeningSessions": "No Listening Sessions",
"MessageNoLogs": "No logs",
"MessageNoMediaFolders": "No Media Folders", "MessageNoMediaFolders": "No Media Folders",
"MessageNoNetworkConnection": "No network connection", "MessageNoNetworkConnection": "No network connection",
"MessageNoPodcastsFound": "No podcasts found", "MessageNoPodcastsFound": "No podcasts found",