Skip to content

Commit

Permalink
Merge pull request #249 from jason5ng32/dev
Browse files Browse the repository at this point in the history
Improvements
  • Loading branch information
jason5ng32 authored Oct 30, 2024
2 parents ea78ada + 2680f41 commit ebfb1d8
Show file tree
Hide file tree
Showing 17 changed files with 278 additions and 63 deletions.
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@ SECURITY_BLACKLIST_LOG_FILE_PATH=""
SECURITY_RATE_LIMIT=""
SECURITY_DELAY_AFTER=""
# Google Analytics
VITE_GOOGLE_ANALYTICS_ID=""
VITE_GOOGLE_ANALYTICS_ID=""
# CURL API
VITE_CURL_IPV4_DOMAIN=""
VITE_CURL_IPV6_DOMAIN=""
VITE_CURL_IPV64_DOMAIN=""
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ You can use the program without adding any environment variables, but if you wan
| `CLOUDFLARE_API` | No | `""` | API Key for Cloudflare, used to obtain AS system information through Cloudflare |
| `MAC_LOOKUP_API_KEY` | No | `""` | API Key for MAC Lookup, used to obtain MAC address information |
| `VITE_GOOGLE_ANALYTICS_ID` | **Yes** | `""` | Google Analytics ID, used to track user behavior |
| `VITE_CURL_IPV4_DOMAIN` | No | `""` | Provides the IPv4 domain for the CURL API to users |
| `VITE_CURL_IPV6_DOMAIN` | No | `""` | Provides the IPv6 domain for the CURL API to users |
| `VITE_CURL_IPV64_DOMAIN` | No | `""` | Provides the dual-stack domain for the CURL API to users |

Note that if any of the CURL series environment variables are missing, the CURL API will not be enabled.

### Using Environment Variables in a Node Environment

Expand Down
5 changes: 5 additions & 0 deletions README_FR.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ Vous pouvez utiliser le programme sans ajouter de variables d'environnement, mai
| `CLOUDFLARE_API` | Non | `""` | Clé API pour Cloudflare, utilisée pour obtenir des informations sur le système AS via Cloudflare |
| `MAC_LOOKUP_API_KEY` | Non | `""` | Clé API pour MAC Lookup, utilisée pour obtenir des informations sur l'adresse MAC via MAC Lookup |
| `VITE_GOOGLE_ANALYTICS_ID` | **Oui** | `""` | Identifiant Google Analytics, utilisé pour l'analyse des utilisateurs |
| `VITE_CURL_IPV4_DOMAIN` | Non | `""` | Fournit aux utilisateurs le domaine IPv4 pour l'API CURL |
| `VITE_CURL_IPV6_DOMAIN` | Non | `""` | Fournit aux utilisateurs le domaine IPv6 pour l'API CURL |
| `VITE_CURL_IPV64_DOMAIN` | Non | `""` | Fournit aux utilisateurs le domaine à pile double pour l'API CURL |

Il est à noter que si l'une quelconque des variables d'environnement de la série CURL est manquante, l'API CURL ne sera pas activée.

### Utilisation des variables d'environnement dans un environnement Node

Expand Down
5 changes: 5 additions & 0 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ docker run -d -p 18966:18966 --name myip --restart always jason5ng32/myip:latest
| `CLOUDFLARE_API` || `""` | Cloudflare 的 API Key,用于通过 Cloudflare 获取 AS 系统的信息 |
| `MAC_LOOKUP_API_KEY` || `""` | MAC 查询的 API Key,用于通过 MAC Lookup 获取 MAC 地址的归属信息 |
| `VITE_GOOGLE_ANALYTICS_ID` | **** | `""` | Google Analytics 的 ID,用于统计访问量 |
| `VITE_CURL_IPV4_DOMAIN` || `""` | 为用户提供 CURL API 的 IPv4 域名 |
| `VITE_CURL_IPV6_DOMAIN` || `""` | 为用户提供 CURL API 的 IPv6 域名 |
| `VITE_CURL_IPV64_DOMAIN` || `""` | 为用户提供 CURL API 的双网络栈域名 |

需要注意的是,如果 CURL 系列的环境变量任意一个缺失,都不会启用 CURL API。

### 在 Node 环境里使用环境变量

Expand Down
Binary file modified common/maxmind-db/GeoLite2-ASN.mmdb
Binary file not shown.
Binary file modified common/maxmind-db/GeoLite2-City.mmdb
Binary file not shown.
26 changes: 17 additions & 9 deletions frontend/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
</div>
<InfoMask :showMaskButton.value="showMaskButton" :infoMaskLevel.value="infoMaskLevel"
:toggleInfoMask="toggleInfoMask" />
<Shell v-if="curlDomainsHadSet" ref="shellRef" />
<QueryIP ref="queryIPRef" />
<Shell ref="shellRef" />
<HelpModal ref="helpModalRef" />
<Footer ref="footerRef" />
<PWA />
Expand Down Expand Up @@ -65,6 +65,7 @@ const userPreferences = computed(() => store.userPreferences);
const shouldRefreshEveryThing = computed(() => store.shouldRefreshEveryThing);
const Status = computed(() => store.mountingStatus);
const openedCard = computed(() => store.currentPath.id);
const curlDomainsHadSet = computed(() => store.curlDomainsHadSet);
// Template 里的 Ref
const navBarRef = ref(null);
Expand Down Expand Up @@ -490,14 +491,6 @@ const ShortcutKeys = (isOriginalSite) => {
},
description: t('shortcutKeys.About'),
},
{
keys: "x",
action: () => {
shellRef.value.openModal();
trackEvent('ShortCut', 'ShortCut', 'Shell');
},
description: t('shortcutKeys.Shell'),
},
// help
{
keys: "?",
Expand All @@ -521,10 +514,25 @@ const ShortcutKeys = (isOriginalSite) => {
},
];
const curlAPI = [
{
keys: "x",
action: () => {
shellRef.value.openModal();
trackEvent('ShortCut', 'ShortCut', 'Shell');
},
description: t('shortcutKeys.Shell'),
},
]
if (isOriginalSite) {
shortcutConfig.push(...invisibilitytest);
}
if (curlDomainsHadSet.value) {
shortcutConfig.push(...curlAPI);
}
return shortcutConfig;
};
Expand Down
62 changes: 57 additions & 5 deletions frontend/components/Footer.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<template>
<footer>
<div id="copyleft">
<p class="text-center">{{ t('page.footerName') }} <a :href="t('page.footerLink')" class="link-dark"
target="_blank" @click="trackEvent('Footer', 'FooterClick', 'Github');" aria-label="Github"><i
class="bi bi-github" :class="{ 'dark-mode': isDarkMode }"
<p class="text-center"><span>Created by Jason Ng with love</span> <a :href="t('page.footerLink')"
class="link-dark" target="_blank" @click="trackEvent('Footer', 'FooterClick', 'Github');"
aria-label="Github"><i class="bi bi-github" :class="{ 'dark-mode': isDarkMode }"
v-tooltip="{ title: t('Tooltips.GithubLink'), placement: 'top' }"></i></a>
</p>
</div>
Expand All @@ -20,7 +20,7 @@
id="About" aria-labelledby="AboutLabel" :data-bs-theme="isDarkMode ? 'dark' : 'light'">
<div class="offcanvas-header mt-3">
<div class="btn-group" role="group">
<template v-for="show in ['about', 'changelog']">
<template v-for="show in ['about', 'changelog', 'specialthanks']">
<input v-model="content" type="radio" class="btn-check" :name="'About_' + show" :id="'About_' + show"
autocomplete="off" :value=show @change="toggleContent(show)">
<label class="btn jn-number" :class="{
Expand Down Expand Up @@ -101,6 +101,21 @@
</div>
</div>
</div>
<div v-if="showSpecialThanks">
<div class="mb-3">
<p>
{{ t('specialthanks.Note1') }}
</p>
</div>

<div v-for="(item, index) in thanksList" :key="index" class="mb-3 fst-italic">
<i class="bi bi-emoji-smile-fill "></i> {{ item.name }}
<a v-if="item.link" :class="[isDarkMode ? 'link-light' : 'link-dark']" :href="item.link" target="_blank">
<i class="bi bi-arrow-up-right-square"></i>
</a>
</div>

</div>

<div id="offcanvasPlaceholder mb-5" class="jn-placeholder mb-5">
</div>
Expand All @@ -124,7 +139,7 @@ import { Offcanvas } from 'bootstrap';
import { useI18n } from 'vue-i18n';
import { trackEvent } from '@/utils/use-analytics';
const {t,tm} = useI18n();
const { t, tm } = useI18n();
const store = useMainStore();
const isDarkMode = computed(() => store.isDarkMode);
Expand All @@ -134,8 +149,40 @@ const configs = computed(() => store.configs);
const content = ref('about');
const showAbout = ref(true);
const showChangelog = ref(false);
const showSpecialThanks = ref(false);
const changelog = reactive(tm('changelog.versions'));
const thanksList = [
{
name: 'Setilis Hu',
link: ''
},
{
name: 'Seven Yu',
link: 'https://github.com/dofy'
},
{
name: 'Nikolai Tschacher',
link: 'https://incolumitas.com/pages/about/'
},
{
name: 'Project Alexandria (Cloudflare)',
link: 'https://www.cloudflare.com/lp/project-alexandria/'
},
{
name: 'Cloudflare Speedtest',
link: 'https://github.com/cloudflare/speedtest'
},
{
name: 'Globalping by jsDelivr',
link: 'https://globalping.io/'
},
{
name: 'ChatGPT',
link: 'https://chatgpt.com/'
}
]
const openAbout = () => {
var offcanvasElement = document.getElementById('About');
var offcanvas = Offcanvas.getInstance(offcanvasElement) || new Offcanvas(offcanvasElement);
Expand All @@ -154,6 +201,7 @@ const offcanvasBody = ref(null);
const toggleContent = (contentType) => {
showAbout.value = contentType === 'about';
showChangelog.value = contentType === 'changelog';
showSpecialThanks.value = contentType === 'specialthanks';
content.value = contentType;
offcanvasBody.scrollTop = 0;
};
Expand All @@ -171,4 +219,8 @@ defineExpose({
.jn-placeholder {
height: 20pt;
}
.jn-heart-color {
color: red;
}
</style>
6 changes: 1 addition & 5 deletions frontend/components/advanced-tools/BrowserInfo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@
<Transition name="slide-fade" mode="out-in">
<div id="browserInfoResult" class="row" v-if="checkingStatus === 'finished'">
<div class="col-lg-8 col-md-8 col-12 mb-4">
<div class="h-100" :class="{
'dark-mode dark-mode-border': isDarkMode,
'card': !isMobile
}">

<div class="h-100">
<div class="card-body row"
:class="[isMobile ? 'p-1 border-1 border-bottom' : '']">
<h3 class="mb-4">{{ t('browserinfo.browser.Infos') }} <i
Expand Down
28 changes: 20 additions & 8 deletions frontend/components/widgets/InfoMask.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
<template>
<button v-show="showMaskButton" class="btn infomask"
:class="infoMaskLevel === 0 ? 'btn-success' : infoMaskLevel === 1 ? 'btn-warning' : 'btn-secondary'"
@click="toggleInfoMask" aria-label="Toggle Info Mask"
v-tooltip="t('Tooltips.InfoMask')">
<button v-show="showMaskButton" class="btn infomask" :class="{
'btn-success': infoMaskLevel === 0,
'btn-warning': infoMaskLevel === 1,
'btn-secondary': infoMaskLevel === 2,
'infomask-no-curl': !curlDomainsHadSet || isMobile
}" @click="toggleInfoMask" aria-label="Toggle Info Mask" v-tooltip="t('Tooltips.InfoMask')">
<i :class="infoMaskLevel === 0 ? 'bi bi-eye' : 'bi bi-eye-slash'"></i>
</button>
</template>

<script setup>
import { onMounted } from 'vue';
import { onMounted, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useMainStore } from '@/store';
const {t} = useI18n();
const { t } = useI18n();
const store = useMainStore();
const isDarkMode = computed(() => store.isDarkMode);
const isMobile = computed(() => store.isMobile);
const curlDomainsHadSet = computed(() => store.curlDomainsHadSet);
const { showMaskButton, infoMaskLevel, toggleInfoMask } = defineProps({
showMaskButton: Boolean,
Expand Down Expand Up @@ -43,8 +51,12 @@ onMounted(() => {
<style scoped>
.infomask {
position: fixed;
bottom: 66px;
right: 20px;
bottom: 112px;
right: 20px;
z-index: 1050;
}
.infomask-no-curl {
bottom: 66px;
}
</style>
16 changes: 13 additions & 3 deletions frontend/components/widgets/PWA.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ const getBrowser = () => {
isOtherBrowser.value = !(androidChrome || desktopChrome || macSafari || iosSafari);
}
const popupCount = () => {
let currentCount = localStorage.getItem('pwaPopupCount') || 0;
currentCount = parseInt(currentCount, 10);
return currentCount;
}
const showPWA = () => {
const pwaInstall = document.getElementsByTagName('pwa-install')[0];
if (!pwaInstall) return;
Expand All @@ -43,6 +49,8 @@ const showPWA = () => {
if (!pwaInstall.isUnderStandaloneMode && pwaInstall.isInstallAvailable) {
pwaInstall.showDialog(true);
const totalPopupCount = popupCount() + 1;
localStorage.setItem('pwaPopupCount', totalPopupCount);
trackEvent('PWA', 'PWAPopup', 'Show');
pwaInstall.addEventListener('pwa-install-success-event', event => {
if (event.detail.message.includes('success')) {
Expand All @@ -54,9 +62,11 @@ const showPWA = () => {
onMounted(() => {
getBrowser();
setTimeout(() => {
showPWA();
}, 30000);
if (popupCount() < 2) {
setTimeout(() => {
showPWA();
}, 30000);
}
});
</script>

Expand Down
Loading

0 comments on commit ebfb1d8

Please sign in to comment.