Skip to content

Commit dea69c9

Browse files
authored
Merge pull request #257 from jason5ng32/dev
Improvements
2 parents 60fd345 + 83d0020 commit dea69c9

File tree

6 files changed

+219
-165
lines changed

6 files changed

+219
-165
lines changed

frontend/components/IpInfos.vue

+169-152
Original file line numberDiff line numberDiff line change
@@ -7,185 +7,192 @@
77
<div class="text-secondary">
88
<p>{{ t('ipInfos.Notes') }}</p>
99
</div>
10-
<div class="row">
11-
<div v-for="(card, index) in ipDataCards.slice(0, ipCardsToShow)" :key="card.id" :ref="card.id" :class="[colClass, {
10+
<div class="row">
11+
<div v-for="(card, index) in ipDataCards.slice(0, ipCardsToShow)" :key="card.id" :ref="card.id" :class="[colClass, {
1212
'jn-opacity': !card.ip || card.ip === t('ipInfos.IPv4Error') || card.ip === t('ipInfos.IPv6Error')
1313
}]">
14-
<div class="card jn-card keyboard-shortcut-card" :class="{
14+
<div class="card jn-card keyboard-shortcut-card" :class="{
1515
'dark-mode dark-mode-border': isDarkMode,
1616
'jn-ip-card1 jn-hover-card': !isMobile && ipGeoSource === 0,
1717
'jn-ip-card2 jn-hover-card': !isMobile && ipGeoSource !== 0,
1818
}">
19-
<div class="card-header jn-ip-title jn-link1"
20-
:class="{ 'dark-mode-title': isDarkMode, 'bg-light': !isDarkMode }" style="font-weight: bold;">
21-
<span>
22-
<i class="bi" :class="'bi-' + (index + 1) + '-circle-fill'"></i>&nbsp;
23-
{{ t('ipInfos.Source') }}: {{ card.source }}</span>
24-
<button @click="refreshCard(card,index)"
25-
:class="['btn', isDarkMode ? 'btn-dark dark-mode-refresh' : 'btn-light']"
26-
:aria-label="'Refresh' + card.source" v-tooltip="t('Tooltips.RefreshIPCard')">
27-
<i class="bi bi-arrow-clockwise"></i></button>
28-
</div>
29-
<div class="p-3 placeholder-glow " :class="{
19+
<div class="card-header jn-ip-title jn-link1"
20+
:class="{ 'dark-mode-title': isDarkMode, 'bg-light': !isDarkMode }" style="font-weight: bold;">
21+
<span>
22+
<i class="bi" :class="'bi-' + (index + 1) + '-circle-fill'"></i>&nbsp;
23+
{{ t('ipInfos.Source') }}: {{ card.source }}</span>
24+
<button @click="refreshCard(card,index)"
25+
:class="['btn', isDarkMode ? 'btn-dark dark-mode-refresh' : 'btn-light']"
26+
:aria-label="'Refresh' + card.source" v-tooltip="t('Tooltips.RefreshIPCard')">
27+
<i class="bi bi-arrow-clockwise"></i></button>
28+
</div>
29+
<div class="p-3 placeholder-glow " :class="{
3030
'dark-mode-title': isDarkMode,
3131
'jn-link2-dark': isDarkMode,
3232
'bg-light': !isDarkMode,
3333
'jn-link2': !isDarkMode
3434
}">
35-
<span class="jn-text col-auto">
36-
<i class="bi bi-pc-display-horizontal"></i>&nbsp;
37-
</span>
38-
<span v-if="card.ip" class="col-10" :class="{ 'jn-ip-font': (isMobile && card.ip.length > 32) }">
39-
{{ card.ip }}&nbsp;
40-
<i v-if="isValidIP(card.ip)"
41-
:class="copiedStatus[card.id] ? 'bi bi-clipboard-check-fill' : 'bi bi-clipboard-plus'"
42-
@click="copyToClipboard(card.ip, card.id)" role="button"
43-
v-tooltip="{ title: t('Tooltips.CopyIP'), placement: 'right' }" :aria-label="'Copy' + card.ip"></i>
44-
</span>
45-
<span v-else class="placeholder col-10"></span>
46-
</div>
35+
<span class="jn-text col-auto">
36+
<i class="bi bi-pc-display-horizontal"></i>&nbsp;
37+
</span>
38+
<span v-if="card.ip" class="col-10" :class="{ 'jn-ip-font': (isMobile && card.ip.length > 32) }">
39+
{{ card.ip }}&nbsp;
40+
<i v-if="isValidIP(card.ip)"
41+
:class="copiedStatus[card.id] ? 'bi bi-clipboard-check-fill' : 'bi bi-clipboard-plus'"
42+
@click="copyToClipboard(card.ip, card.id)" role="button"
43+
v-tooltip="{ title: t('Tooltips.CopyIP'), placement: 'right' }" :aria-label="'Copy' + card.ip"></i>
44+
</span>
45+
<span v-else class="placeholder col-10"></span>
46+
</div>
4747

4848

49-
<div v-if="(card.asn) || (card.ip === t('ipInfos.IPv4Error')) || (card.ip === t('ipInfos.IPv6Error')) || card.ip === '2001:4860:4860::8888'
49+
<div v-if="(card.asn) || card.ip === '2001:4860:4860::8888'
5050
" class="card-body" :id="'IPInfo-' + (index + 1)">
51-
<ul class="list-group list-group-flush" v-if="card.country_name">
52-
53-
<img v-if="isMapShown" :src="isDarkMode ? card.mapUrl_dark : card.mapUrl"
54-
class="card-img-top jn-map-image" alt="Map">
55-
56-
<li class="jn-list-group-item"
57-
:class="{ 'dark-mode': isDarkMode, 'mobile-list': isMobile && isCardsCollapsed }">
58-
<span class="jn-text col-auto">
59-
<i class="bi bi-geo-alt-fill"></i> {{ t('ipInfos.Country') }} :&nbsp;
60-
</span>
61-
<span class="col-10 ">
62-
{{ card.country_name }}
63-
<span v-if="card.country_code" :class="'jn-fl fi fi-' + card.country_code.toLowerCase()"></span>
51+
<ul class="list-group list-group-flush" v-if="card.country_name">
52+
53+
<img v-if="isMapShown" :src="isDarkMode ? card.mapUrl_dark : card.mapUrl"
54+
class="card-img-top jn-map-image" alt="Map">
55+
56+
<li class="jn-list-group-item"
57+
:class="{ 'dark-mode': isDarkMode, 'mobile-list': isMobile && isCardsCollapsed }">
58+
<span class="jn-text col-auto">
59+
<i class="bi bi-geo-alt-fill"></i> {{ t('ipInfos.Country') }} :&nbsp;
60+
</span>
61+
<span class="col-10 ">
62+
{{ card.country_name }}
63+
<span v-if="card.country_code" :class="'jn-fl fi fi-' + card.country_code.toLowerCase()"></span>
64+
</span>
65+
</li>
66+
67+
<li v-show="!isMobile || !isCardsCollapsed" class="jn-list-group-item"
68+
:class="{ 'dark-mode': isDarkMode }">
69+
<span class="jn-text col-auto">
70+
<i class="bi bi-houses"></i>
71+
{{ t('ipInfos.Region') }} :&nbsp;
72+
</span>
73+
<span class="col-10 ">
74+
{{ card.region }}
75+
</span>
76+
</li>
77+
78+
<li v-show="!isMobile || !isCardsCollapsed" class="jn-list-group-item"
79+
:class="{ 'dark-mode': isDarkMode }">
80+
<span class="jn-text col-auto">
81+
<i class="bi bi-sign-turn-right"></i>
82+
{{ t('ipInfos.City') }} :&nbsp;
83+
</span>
84+
<span class="col-10 ">
85+
{{ card.city }}
86+
</span>
87+
</li>
88+
89+
<li v-show="!isMobile || !isCardsCollapsed" class="jn-list-group-item"
90+
:class="{ 'dark-mode': isDarkMode }">
91+
<span class="jn-text col-auto">
92+
<i class="bi bi-ethernet"></i>
93+
{{ t('ipInfos.ISP') }} :&nbsp;
94+
</span>
95+
<span class="col-10 ">
96+
{{ card.isp }}
97+
</span>
98+
</li>
99+
100+
<li
101+
v-show="(!isMobile || !isCardsCollapsed) && ipGeoSource === 0 && card.type !== t('ipInfos.proxyDetect.type.unknownType')"
102+
class="jn-list-group-item" :class="{ 'dark-mode': isDarkMode }">
103+
<span class="jn-text col-auto">
104+
<i class="bi bi-reception-4"></i>
105+
{{ t('ipInfos.type') }} :&nbsp;
106+
</span>
107+
<span class="col-10 ">
108+
{{ card.type }}
109+
<span v-if="card.proxyOperator !== 'unknown'">
110+
( {{ card.proxyOperator }} )
64111
</span>
65-
</li>
66-
67-
<li v-show="!isMobile || !isCardsCollapsed" class="jn-list-group-item"
68-
:class="{ 'dark-mode': isDarkMode }">
69-
<span class="jn-text col-auto">
70-
<i class="bi bi-houses"></i>
71-
{{ t('ipInfos.Region') }} :&nbsp;
112+
</span>
113+
</li>
114+
115+
<li
116+
v-show="(!isMobile || !isCardsCollapsed) && ipGeoSource === 0 && card.isProxy !== t('ipInfos.proxyDetect.unknownProxyType')"
117+
class="jn-list-group-item" :class="{ 'dark-mode': isDarkMode }">
118+
<span class="jn-text col-auto">
119+
<i class="bi bi-shield-fill-check"></i>
120+
{{ t('ipInfos.isProxy') }} :&nbsp;
121+
</span>
122+
<span class="col-10 ">
123+
{{ card.isProxy }}
124+
<span v-if="card.proxyProtocol !== t('ipInfos.proxyDetect.unknownProtocol')">
125+
( {{ card.proxyProtocol }} )
72126
</span>
73-
<span class="col-10 ">
74-
{{ card.region }}
75-
</span>
76-
</li>
77-
78-
<li v-show="!isMobile || !isCardsCollapsed" class="jn-list-group-item"
79-
:class="{ 'dark-mode': isDarkMode }">
80-
<span class="jn-text col-auto">
81-
<i class="bi bi-sign-turn-right"></i>
82-
{{ t('ipInfos.City') }} :&nbsp;
83-
</span>
84-
<span class="col-10 ">
85-
{{ card.city }}
127+
</span>
128+
</li>
129+
130+
<li v-show="!isMobile || !isCardsCollapsed" class="jn-list-group-item border-0"
131+
:class="{ 'dark-mode': isDarkMode }">
132+
<span class="jn-text col-auto">
133+
<i class="bi bi-buildings"></i>
134+
{{ t('ipInfos.ASN') }} :&nbsp;
135+
</span>
136+
<span v-if="card.asnlink" class="col-9 ">
137+
{{ card.asn }} <i v-if="configs.cloudFlare" class="bi bi-info-circle"
138+
@click="getASNInfo(card.asn, index)" data-bs-toggle="collapse"
139+
:data-bs-target="'#' + 'collapseASNInfo-' + index" aria-expanded="false"
140+
:aria-controls="'collapseASNInfo-' + index" role="button"
141+
:aria-label="'Display AS Info of' + card.asn"
142+
v-tooltip="{ title: t('Tooltips.ShowASNInfo'), placement: 'right' }"></i>
143+
</span>
144+
</li>
145+
146+
<div class="collapse alert alert-light placeholder-glow lh-lg fw-bold p-0"
147+
:id="'collapseASNInfo-' + index" :data-bs-theme="isDarkMode ? 'dark' : ''">
148+
149+
<!-- 通过将 collapse 的 padding 设置为 0,然后添加一个子 div 设置 padding 的方式,避免 Bootstrap 的 collapse 发生卡顿,很奇怪的 bug -->
150+
151+
<div class="p-3">
152+
<span v-if="asnInfos[card.asn]">
153+
<i class="bi bi-info-circle-fill"></i> <span class="fw-light">{{ t('ipInfos.ASNInfo.note')
154+
}}</span>
155+
<br />
156+
<template v-for="(item,key) in asnInfos[card.asn]">
157+
<span class="fw-light">
158+
{{ t(`ipInfos.ASNInfo.${key}`) }}
159+
</span>
160+
{{ item }}
161+
<br />
162+
</template>
86163
</span>
87-
</li>
88164

89-
<li v-show="!isMobile || !isCardsCollapsed" class="jn-list-group-item"
90-
:class="{ 'dark-mode': isDarkMode }">
91-
<span class="jn-text col-auto">
92-
<i class="bi bi-ethernet"></i>
93-
{{ t('ipInfos.ISP') }} :&nbsp;
94-
</span>
95-
<span class="col-10 ">
96-
{{ card.isp }}
97-
</span>
98-
</li>
99-
100-
<li
101-
v-show="(!isMobile || !isCardsCollapsed) && ipGeoSource === 0 && card.type !== t('ipInfos.proxyDetect.type.unknownType')"
102-
class="jn-list-group-item" :class="{ 'dark-mode': isDarkMode }">
103-
<span class="jn-text col-auto">
104-
<i class="bi bi-reception-4"></i>
105-
{{ t('ipInfos.type') }} :&nbsp;
106-
</span>
107-
<span class="col-10 ">
108-
{{ card.type }}
109-
<span v-if="card.proxyOperator !== 'unknown'">
110-
( {{ card.proxyOperator }} )
111-
</span>
112-
</span>
113-
</li>
114-
115-
<li
116-
v-show="(!isMobile || !isCardsCollapsed) && ipGeoSource === 0 && card.isProxy !== t('ipInfos.proxyDetect.unknownProxyType')"
117-
class="jn-list-group-item" :class="{ 'dark-mode': isDarkMode }">
118-
<span class="jn-text col-auto">
119-
<i class="bi bi-shield-fill-check"></i>
120-
{{ t('ipInfos.isProxy') }} :&nbsp;
121-
</span>
122-
<span class="col-10 ">
123-
{{ card.isProxy }}
124-
<span v-if="card.proxyProtocol !== t('ipInfos.proxyDetect.unknownProtocol')">
125-
( {{ card.proxyProtocol }} )
165+
<span v-else>
166+
<span v-for="(colSize, index) in placeholderSizes" :key="index"
167+
:class="{ 'dark-mode': isDarkMode }">
168+
<span :class="`placeholder col-${colSize}`"></span>
126169
</span>
127170
</span>
128-
</li>
129-
130-
<li v-show="!isMobile || !isCardsCollapsed" class="jn-list-group-item border-0"
131-
:class="{ 'dark-mode': isDarkMode }">
132-
<span class="jn-text col-auto">
133-
<i class="bi bi-buildings"></i>
134-
{{ t('ipInfos.ASN') }} :&nbsp;
135-
</span>
136-
<span v-if="card.asnlink" class="col-9 ">
137-
{{ card.asn }} <i v-if="configs.cloudFlare" class="bi bi-info-circle"
138-
@click="getASNInfo(card.asn, index)" data-bs-toggle="collapse"
139-
:data-bs-target="'#' + 'collapseASNInfo-' + index" aria-expanded="false"
140-
:aria-controls="'collapseASNInfo-' + index" role="button"
141-
:aria-label="'Display AS Info of' + card.asn"
142-
v-tooltip="{ title: t('Tooltips.ShowASNInfo'), placement: 'right' }"></i>
143-
</span>
144-
</li>
145-
146-
<div class="collapse alert alert-light placeholder-glow lh-lg fw-bold p-0"
147-
:id="'collapseASNInfo-' + index" :data-bs-theme="isDarkMode ? 'dark' : ''">
148-
149-
<!-- 通过将 collapse 的 padding 设置为 0,然后添加一个子 div 设置 padding 的方式,避免 Bootstrap 的 collapse 发生卡顿,很奇怪的 bug -->
150-
151-
<div class="p-3">
152-
<span v-if="asnInfos[card.asn]">
153-
<i class="bi bi-info-circle-fill"></i> <span class="fw-light">{{ t('ipInfos.ASNInfo.note')
154-
}}</span>
155-
<br />
156-
<template v-for="(item,key) in asnInfos[card.asn]">
157-
<span class="fw-light">
158-
{{ t(`ipInfos.ASNInfo.${key}`) }}
159-
</span>
160-
{{ item }}
161-
<br />
162-
</template>
163-
</span>
164-
165-
<span v-else>
166-
<span v-for="(colSize, index) in placeholderSizes" :key="index"
167-
:class="{ 'dark-mode': isDarkMode }">
168-
<span :class="`placeholder col-${colSize}`"></span>
169-
</span>
170-
</span>
171-
</div>
172171
</div>
173-
</ul>
174-
</div>
172+
</div>
173+
</ul>
174+
</div>
175175

176-
<div v-else class="card-body">
177-
<ul class="list-group list-group-flush placeholder-glow">
178-
<li v-for="(colSize, index) in placeholderSizes" :key="index" class="list-group-item jn-list-group-item"
179-
:class="{ 'dark-mode': isDarkMode }">
180-
<span :class="`placeholder col-${colSize}`"></span>
181-
</li>
182-
</ul>
176+
<div v-else-if="(card.ip === t('ipInfos.IPv4Error')) || (card.ip === t('ipInfos.IPv6Error'))"
177+
class="card-body jn-ip-error">
178+
<div>
179+
<IPErrorIcon />
183180
</div>
181+
</div>
184182

183+
<div v-else class="card-body">
184+
<ul class="list-group list-group-flush placeholder-glow">
185+
<li v-for="(colSize, index) in placeholderSizes" :key="index" class="list-group-item jn-list-group-item"
186+
:class="{ 'dark-mode': isDarkMode }">
187+
<span :class="`placeholder col-${colSize}`"></span>
188+
</li>
189+
</ul>
185190
</div>
191+
186192
</div>
187193
</div>
188194
</div>
195+
</div>
189196
</template>
190197

191198

@@ -201,6 +208,9 @@ import { getIPFromIPIP, getIPFromCloudflare_V4, getIPFromCloudflare_V6, getIPFro
201208
202209
const { t } = useI18n();
203210
211+
// 导入 IP 错误图标
212+
import IPErrorIcon from './svgicons/IPError.vue';
213+
204214
// Store
205215
const store = useMainStore();
206216
const isDarkMode = computed(() => store.isDarkMode);
@@ -470,7 +480,7 @@ const refreshCard = (card, index) => {
470480
break;
471481
case 3:
472482
fetchIP(3, getIPFromIPChecking64);
473-
break;
483+
break;
474484
case 4:
475485
fetchIP(4, getIPFromIPChecking4);
476486
break;
@@ -577,6 +587,13 @@ defineExpose({
577587
z-index: 1;
578588
}
579589
590+
.jn-ip-error {
591+
display: flex;
592+
justify-content: space-evenly;
593+
align-items: center;
594+
flex-direction: column;
595+
}
596+
580597
.dropdown-item.disabled,
581598
.dropdown-item:disabled {
582599
text-decoration: line-through;

0 commit comments

Comments
 (0)