console-pro-free/console-pro/panel/index.js

477 lines
16 KiB
JavaScript
Raw Normal View History

2023-11-01 02:27:59 +00:00
const clipboard = require(Editor.url('packages://console-pro/node_modules/clipboard/dist/clipboard.js'))
const axios = require(Editor.url('packages://console-pro/node_modules/axios/dist/axios.js'))
const packageJSON = require(Editor.url('packages://console-pro/package.json'))
const childProcess = require('child_process')
const path = require('path')
const fs = require('fs')
const os = require('os')
const translate = (key) => Editor.T(`${packageJSON.name}.${key}`)
var vm = null
// panel/index.js, this filename needs to match the one registered in package.json
Editor.Panel.extend({
// css style for panel
style: fs.readFileSync(Editor.url('packages://console-pro/static/style/default/index.css', 'utf8')),
// html template for panel
template: fs.readFileSync(Editor.url('packages://console-pro/static/template/default/index.html', 'utf8')),
// element and variable binding
$: {
app: '#app',
logDetail: '#log-detail'
},
close() {
},
// method executed when template and styles are successfully loaded and initialized
ready () {
vm = new window.Vue({
el: this.shadowRoot,
data() {
return {
openSettingsI18n: translate('openSettings'),
clearLogI18n: translate('clearLog'),
openLogI18n: translate('openLog'),
searchPlaceholderI18n: translate('searchPlaceholder'),
iconI18n: translate('icon'),
timeI18n: translate('time'),
typeI18n: translate('type'),
contentI18n: translate('content'),
copyI18n: translate('copy'),
deleteI18n: translate('delete'),
expandI18n: translate('expand'),
collapseI18n: translate('collapse'),
developI18n: translate('develop'),
backI18n: translate('back'),
currentPage: 'log',
settingsImgPath: Editor.url('packages://console-pro/static/images/settings.png'),
clearImgPath: Editor.url('packages://console-pro/static/images/clear.png'),
openLogImgPath: Editor.url('packages://console-pro/static/images/log.png'),
searchImgPath: Editor.url('packages://console-pro/static/images/search.png'),
matchCaseImgPath: Editor.url('packages://console-pro/static/images/match-case.png'),
matchWholeImgPath: Editor.url('packages://console-pro/static/images/match-whole.png'),
matchRegImgPath: Editor.url('packages://console-pro/static/images/match-reg.png'),
logNumImgPath: Editor.url('packages://console-pro/static/images/log-color.png'),
infoNumImgPath: Editor.url('packages://console-pro/static/images/info-color.png'),
warnNumImgPath: Editor.url('packages://console-pro/static/images/warn-color.png'),
errorNumImgPath: Editor.url('packages://console-pro/static/images/error-color.png'),
copyImgPath: Editor.url('packages://console-pro/static/images/copy.png'),
deleteImgPath: Editor.url('packages://console-pro/static/images/delete.png'),
expandImgPath: Editor.url('packages://console-pro/static/images/expand.png'),
collapseImgPath: Editor.url('packages://console-pro/static/images/collapse.png'),
isMatchCase: false,
isMatchWhole: false,
isMatchReg: false,
matchCaseBtnClass: 'transparent',
matchWholeBtnClass: 'transparent',
matchRegBtnClass: 'transparent',
logNum: 0,
infoNum: 0,
warnNum: 0,
errorNum: 0,
isLogTypeShown: true,
isInfoTypeShown: true,
isWarnTypeShown: true,
isErrorTypeShown: true,
currentLogDataArray: [],
searchResultArray: [],
keyword: '',
isClearLogOnPreview: false,
isCurrentItemExpanded: false,
currentLogIndex: 0,
isSearching: false,
logDetailHTML: null,
menuHTML: null
}
},
created() {
// 如果不需要更新提示,注释这行代码即可
// this.checkUpdate()
},
computed: {
currentLogDataArrayComputed() {
return this.currentLogDataArray
}
},
methods: {
checkUpdate() {
// 检查是否有更新
axios.get('https://la-vie.gitee.io/console-pro2x/package.json', {headers: {'Cache-Control': 'no-cache'}})
.then(function(response) {
let remoteVersion = response.data.version;
if (packageJSON.version != remoteVersion) {
Editor.warn(`[v${remoteVersion}] ${translate('updateWarn')}`);
}
});
},
storeELements(event) {
// v-el和v-ref都获取不到只能通过这种方式获取先
// 获取id为log-detail的元素
this.logDetailHTML = event.currentTarget
// 获取右键菜单元素
this.menuHTML = event.currentTarget.parentElement.parentElement.getElementsByClassName('menu')[0]
},
back() {
this.currentPage = 'log'
},
setClearOnPreview() {
this.isClearLogOnPreview = !this.isClearLogOnPreview
},
escape(str) {
return str.replace(/[\-\/\\\^\$\*\+\?\.\(\)\|\[\]\{\}]/g, '\\$&')
},
search(keyword) {
// 关键词搜索
this.keyword = keyword
// 没有关键词则直接返回
if (!keyword.length) {
this.isSearching = false
return
}
// 构造正则表达式
this.isSearching = true
this.searchResultArray = []
let matchCaseRegPart = 'i'
let matchWholeRegPart1 = ''
let matchWholeRegPart2 = ''
let regStr = keyword
if (!this.isMatchReg) {
regStr = this.escape(regStr)
}
if (this.isMatchCase) {
matchCaseRegPart = ''
}
if (this.isMatchWhole) {
matchWholeRegPart1 = '\\b'
matchWholeRegPart2 = '\\b'
}
regStr = `${matchWholeRegPart1}${regStr}${matchWholeRegPart2}`
let regExp = new RegExp(regStr, matchCaseRegPart+'g')
// 将符合条件的日志放入searchResultArray中
for (let i=0; i<this.currentLogDataArray.length; i++) {
if (this.currentLogDataArray[i].message.search(regExp) > -1) {
this.searchResultArray.push(this.currentLogDataArray[i])
}
}
},
showContextMenu(event, index) {
// 显示右键菜单
event.preventDefault()
let logDetailLeft = this.logDetailHTML.getBoundingClientRect().left
let logDetailTop = this.logDetailHTML.getBoundingClientRect().top
let x = event.clientX - logDetailLeft
let y = event.clientY - logDetailTop
if (y > this.logDetailHTML.clientHeight/2) {
this.menuHTML.style.top = y - 30 + 'px'
}
else {
this.menuHTML.style.top = y + 30 + 'px'
}
this.menuHTML.style.left = x + 10+ 'px'
this.currentLogIndex = index
this.isCurrentItemExpanded = this.currentLogDataArray[index].isExpanded
},
hideContextMenu(event) {
if (this.menuHTML) {
this.menuHTML.style.top = '-1000px'
}
},
copyLog(index) {
clipboard.copy(this.currentLogDataArray[index].message)
},
deleteLog(index) {
let logType = this.currentLogDataArray[index].type
this.currentLogDataArray.splice(index, 1)
if (logType == 'log') {
this.logNum -= 1
}
else if (logType == 'info') {
this.infoNum -= 1
}
else if (logType == 'warn') {
this.warnNum -= 1
}
else if (logType == 'error') {
this.errorNum -= 1
}
},
truncate(item) {
// 截断
// 若处于展开状态,则不截断
if (item.isExpanded) {
return item.message
}
// 若大于100个字符则截断
if (item.message.length > 100) {
return item.message.substring(0, 100) + '...'
}
return item.message
},
clearLog() {
// 清空当前显示的日志
Editor.Ipc.sendToMain('console-pro:clear-log')
this.currentLogDataArray = []
this.previousLogDataArray = JSON.stringify([])
this.logNum = 0
this.infoNum = 0
this.warnNum = 0
this.errorNum = 0
},
openSettings() {
// 进入到设置页面
this.currentPage = 'settings'
},
openLog() {
// 打开日志文件
let logFilePath = path.join(os.homedir(), '.CocosCreator/logs/CocosCreator.log')
if (fs.existsSync(logFilePath)) {
if (os.type() == "Windows_NT") {
childProcess.exec(`explorer.exe ${logFilePath}`)
}
else if (os.type() == "Darwin") {
childProcess.exec(`open ${logFilePath}`)
}
}
else {
Editor.Dialog.messageBox({
message: translate('noLogFile'),
buttons: ['Ok'],
title: 'Cocos Console Pro',
})
}
},
onMatchCaseBtnClicked() {
// 当点击了大小写匹配按钮
this.isMatchCase = !this.isMatchCase
this.matchCaseBtnClass = this.isMatchCase ? 'blue transparent' : 'transparent'
this.search(this.keyword)
},
onMatchWholeBtnClicked() {
// 当点击了全字符匹配按钮
this.isMatchWhole = !this.isMatchWhole
this.matchWholeBtnClass = this.isMatchWhole ? 'blue transparent' : 'transparent'
this.search(this.keyword)
},
onMatchRegBtnClicked() {
// 当点击了正则匹配按钮
this.isMatchReg = !this.isMatchReg
this.matchRegBtnClass = this.isMatchReg ? 'blue transparent' : 'transparent'
this.search(this.keyword)
},
showHideCertainTypeOfLog(logType) {
// 当点击了右上角某个类型日志,可显示或隐藏对应类型的所有日志
if (logType == 'log') {
this.isLogTypeShown = !this.isLogTypeShown
this.logNumImgPath = this.isLogTypeShown ? Editor.url('packages://console-pro/static/images/log-color.png') : Editor.url('packages://console-pro/static/images/log-gray.png')
for (let i=0; i<this.currentLogDataArray.length; i++) {
if (this.currentLogDataArray[i]['type'] == 'log') {
this.currentLogDataArray[i]['isShown'] = this.isLogTypeShown
}
}
}
else if (logType == 'info') {
this.isInfoTypeShown = !this.isInfoTypeShown
this.infoNumImgPath = this.isInfoTypeShown ? Editor.url('packages://console-pro/static/images/info-color.png') : Editor.url('packages://console-pro/static/images/info-gray.png')
for (let i=0; i<this.currentLogDataArray.length; i++) {
if (this.currentLogDataArray[i]['type'] == 'info') {
this.currentLogDataArray[i]['isShown'] = this.isInfoTypeShown
}
}
}
else if (logType == 'warn') {
this.isWarnTypeShown = !this.isWarnTypeShown
this.warnNumImgPath = this.isWarnTypeShown ? Editor.url('packages://console-pro/static/images/warn-color.png') : Editor.url('packages://console-pro/static/images/warn-gray.png')
for (let i=0; i<this.currentLogDataArray.length; i++) {
if (this.currentLogDataArray[i]['type'] == 'warn') {
this.currentLogDataArray[i]['isShown'] = this.isWarnTypeShown
}
}
}
else if (logType == 'error') {
this.isErrorTypeShown = !this.isErrorTypeShown
this.errorNumImgPath = this.isErrorTypeShown ? Editor.url('packages://console-pro/static/images/error-color.png') : Editor.url('packages://console-pro/static/images/error-gray.png')
for (let i=0; i<this.currentLogDataArray.length; i++) {
if (this.currentLogDataArray[i]['type'] == 'error') {
this.currentLogDataArray[i]['isShown'] = this.isErrorTypeShown
}
}
}
// 滑动条下滑
this.$nextTick(()=>{
if (this.isScrollAtBottom()) {
this.logDetailHTML.scrollTop = Number.MAX_SAFE_INTEGER
}
})
},
expandLog(index) {
// 展开日志
this.currentLogDataArray[index].isExpanded = !this.currentLogDataArray[index].isExpanded
},
logTypeTologPath(logType) {
// 将日志类型转换为日志图标
return Editor.url(`packages://console-pro/static/images/${logType}-color.png`)
},
timeStampToDateTime(timestamp) {
// 将时间戳转换为日期时间
let date = new Date(timestamp)
let year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
let hour = date.getHours()
let minute = date.getMinutes()
let second = date.getSeconds()
// 小于10的话前面补齐'0'
let monthStr = month < 10 ? '0'+month : month.toString()
let dayStr = day < 10 ? '0'+day : day.toString()
let hourStr = hour < 10 ? '0'+hour : hour.toString()
let minuteStr = minute < 10 ? '0'+minute : minute.toString()
let secondStr = second < 10 ? '0'+second : second.toString()
return `${year}-${monthStr}-${dayStr} ${hourStr}:${minuteStr}:${secondStr}`
},
isScrollAtBottom() {
// 判断滚动条是否在底部
if (!this.logDetailHTML) {
return false
}
let clientHeight = this.logDetailHTML.clientHeight
let scrollTop = this.logDetailHTML.scrollTop
let scrollHeight = this.logDetailHTML.scrollHeight
if (clientHeight + scrollTop >= scrollHeight * 0.98) {
return true
}
return false
},
updateLog(logType, msg) {
let item = {
'type': logType,
'message': msg,
'time': new Date().valueOf(),
'isExpanded': false
}
if (logType == 'log') {
this.logNum += 1
item.isShown = this.isLogTypeShown
}
else if (logType == 'info') {
this.infoNum += 1
item.isShown = this.isInfoTypeShown
}
else if (logType == 'warn') {
this.warnNum += 1
item.isShown = this.isWarnTypeShown
}
else if (logType == 'error') {
this.errorNum += 1
item.isShown = this.isErrorTypeShown
}
this.currentLogDataArray.push(item)
// 滑动条下滑
this.$nextTick(()=>{
if (this.isScrollAtBottom()) {
this.logDetailHTML.scrollTop = Number.MAX_SAFE_INTEGER
}
})
}
}
})
},
// register your ipc messages here
messages: {
'editor:console-log': (event, msg)=>{
vm.updateLog('log', msg)
},
'editor:console-success': (event, msg)=>{
vm.updateLog('log', msg)
},
'editor:console-failed': (event, msg)=>{
vm.updateLog('error', msg)
},
'editor:console-info': (event, msg)=>{
vm.updateLog('info', msg)
},
'editor:console-warn': (event, msg)=>{
vm.updateLog('warn', msg)
},
'editor:console-error': (event, msg)=>{
vm.updateLog('error', msg)
},
'scene:play-on-device': (event)=>{
if (vm.isClearLogOnPreview) {
vm.clearLog()
}
},
}
});