Browse Source

feat(tabs): collapse settings and xray tab bars to evenly-spread icons

On phones the five Settings tabs and six Xray tabs overflowed the
viewport. Now the tab labels are stripped (v-if="!isMobile"), the
nav-list stretches to full width via display:flex + width:100%, and
each tab claims an equal share with flex:1 1 0 so the icons spread
across the row instead of bunching. Icons bumped to 18px with a
tooltip carrying the original label for discoverability.
MHSanaei 1 day ago
parent
commit
18614bd6ea
2 changed files with 104 additions and 18 deletions
  1. 50 11
      frontend/src/pages/settings/SettingsPage.vue
  2. 54 7
      frontend/src/pages/xray/XrayPage.vue

+ 50 - 11
frontend/src/pages/settings/SettingsPage.vue

@@ -228,39 +228,49 @@ onBeforeUnmount(() => {
                 </a-col>
                 </a-col>
 
 
                 <a-col :span="24">
                 <a-col :span="24">
-                  <a-tabs :active-key="activeTabKey" @change="onTabChange">
+                  <a-tabs :active-key="activeTabKey" :class="{ 'icons-only': isMobile }" @change="onTabChange">
                     <a-tab-pane key="1" class="tab-pane">
                     <a-tab-pane key="1" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <SettingOutlined />
-                        <span>{{ t('pages.settings.panelSettings') }}</span>
+                        <a-tooltip :title="isMobile ? t('pages.settings.panelSettings') : null">
+                          <SettingOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.settings.panelSettings') }}</span>
                       </template>
                       </template>
                       <GeneralTab :all-setting="allSetting" />
                       <GeneralTab :all-setting="allSetting" />
                     </a-tab-pane>
                     </a-tab-pane>
                     <a-tab-pane key="2" class="tab-pane">
                     <a-tab-pane key="2" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <SafetyOutlined />
-                        <span>{{ t('pages.settings.securitySettings') }}</span>
+                        <a-tooltip :title="isMobile ? t('pages.settings.securitySettings') : null">
+                          <SafetyOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.settings.securitySettings') }}</span>
                       </template>
                       </template>
                       <SecurityTab :all-setting="allSetting" />
                       <SecurityTab :all-setting="allSetting" />
                     </a-tab-pane>
                     </a-tab-pane>
                     <a-tab-pane key="3" class="tab-pane">
                     <a-tab-pane key="3" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <MessageOutlined />
-                        <span>{{ t('pages.settings.TGBotSettings') }}</span>
+                        <a-tooltip :title="isMobile ? t('pages.settings.TGBotSettings') : null">
+                          <MessageOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.settings.TGBotSettings') }}</span>
                       </template>
                       </template>
                       <TelegramTab :all-setting="allSetting" />
                       <TelegramTab :all-setting="allSetting" />
                     </a-tab-pane>
                     </a-tab-pane>
                     <a-tab-pane key="4" class="tab-pane">
                     <a-tab-pane key="4" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <CloudServerOutlined />
-                        <span>{{ t('pages.settings.subSettings') }}</span>
+                        <a-tooltip :title="isMobile ? t('pages.settings.subSettings') : null">
+                          <CloudServerOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.settings.subSettings') }}</span>
                       </template>
                       </template>
                       <SubscriptionGeneralTab :all-setting="allSetting" />
                       <SubscriptionGeneralTab :all-setting="allSetting" />
                     </a-tab-pane>
                     </a-tab-pane>
                     <a-tab-pane v-if="allSetting.subJsonEnable || allSetting.subClashEnable" key="5" class="tab-pane">
                     <a-tab-pane v-if="allSetting.subJsonEnable || allSetting.subClashEnable" key="5" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <CodeOutlined />
-                        <span>{{ t('pages.settings.subSettings') }} (Formats)</span>
+                        <a-tooltip :title="isMobile ? `${t('pages.settings.subSettings')} (Formats)` : null">
+                          <CodeOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.settings.subSettings') }} (Formats)</span>
                       </template>
                       </template>
                       <SubscriptionFormatsTab :all-setting="allSetting" />
                       <SubscriptionFormatsTab :all-setting="allSetting" />
                     </a-tab-pane>
                     </a-tab-pane>
@@ -333,4 +343,33 @@ onBeforeUnmount(() => {
 .tab-pane {
 .tab-pane {
   padding-top: 20px;
   padding-top: 20px;
 }
 }
+
+.icons-only :deep(.ant-tabs-nav) {
+  margin-bottom: 8px;
+}
+
+.icons-only :deep(.ant-tabs-nav-wrap) {
+  width: 100%;
+}
+
+.icons-only :deep(.ant-tabs-nav-list) {
+  display: flex;
+  width: 100%;
+}
+
+.icons-only :deep(.ant-tabs-tab) {
+  flex: 1 1 0;
+  justify-content: center;
+  margin: 0;
+  padding: 10px 0;
+}
+
+.icons-only :deep(.ant-tabs-tab .anticon) {
+  margin: 0;
+  font-size: 18px;
+}
+
+.icons-only :deep(.ant-tabs-nav-operations) {
+  display: none;
+}
 </style>
 </style>

+ 54 - 7
frontend/src/pages/xray/XrayPage.vue

@@ -301,10 +301,13 @@ onBeforeUnmount(() => {
 
 
                 <!-- Tabs -->
                 <!-- Tabs -->
                 <a-col :span="24">
                 <a-col :span="24">
-                  <a-tabs :active-key="activeTabKey" @change="onTabChange">
+                  <a-tabs :active-key="activeTabKey" :class="{ 'icons-only': isMobile }" @change="onTabChange">
                     <a-tab-pane key="tpl-basic" class="tab-pane">
                     <a-tab-pane key="tpl-basic" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <SettingOutlined /> <span>{{ t('pages.xray.basicTemplate') }}</span>
+                        <a-tooltip :title="isMobile ? t('pages.xray.basicTemplate') : null">
+                          <SettingOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.xray.basicTemplate') }}</span>
                       </template>
                       </template>
                       <BasicsTab :template-settings="templateSettings" :outbound-test-url="outboundTestUrl"
                       <BasicsTab :template-settings="templateSettings" :outbound-test-url="outboundTestUrl"
                         :warp-exist="warpExist" :nord-exist="nordExist"
                         :warp-exist="warpExist" :nord-exist="nordExist"
@@ -314,7 +317,10 @@ onBeforeUnmount(() => {
 
 
                     <a-tab-pane key="tpl-routing" class="tab-pane">
                     <a-tab-pane key="tpl-routing" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <SwapOutlined /> <span>{{ t('pages.xray.Routings') }}</span>
+                        <a-tooltip :title="isMobile ? t('pages.xray.Routings') : null">
+                          <SwapOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.xray.Routings') }}</span>
                       </template>
                       </template>
                       <RoutingTab :template-settings="templateSettings" :inbound-tags="inboundTags"
                       <RoutingTab :template-settings="templateSettings" :inbound-tags="inboundTags"
                         :client-reverse-tags="clientReverseTags" :is-mobile="isMobile" />
                         :client-reverse-tags="clientReverseTags" :is-mobile="isMobile" />
@@ -322,7 +328,10 @@ onBeforeUnmount(() => {
 
 
                     <a-tab-pane key="tpl-outbound" class="tab-pane">
                     <a-tab-pane key="tpl-outbound" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <UploadOutlined /> <span>{{ t('pages.xray.Outbounds') }}</span>
+                        <a-tooltip :title="isMobile ? t('pages.xray.Outbounds') : null">
+                          <UploadOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.xray.Outbounds') }}</span>
                       </template>
                       </template>
                       <OutboundsTab :template-settings="templateSettings" :outbounds-traffic="outboundsTraffic"
                       <OutboundsTab :template-settings="templateSettings" :outbounds-traffic="outboundsTraffic"
                         :outbound-test-states="outboundTestStates" :testing-all="testingAll"
                         :outbound-test-states="outboundTestStates" :testing-all="testingAll"
@@ -334,21 +343,30 @@ onBeforeUnmount(() => {
 
 
                     <a-tab-pane key="tpl-balancer" class="tab-pane">
                     <a-tab-pane key="tpl-balancer" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <ClusterOutlined /> <span>{{ t('pages.xray.Balancers') }}</span>
+                        <a-tooltip :title="isMobile ? t('pages.xray.Balancers') : null">
+                          <ClusterOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.xray.Balancers') }}</span>
                       </template>
                       </template>
                       <BalancersTab :template-settings="templateSettings" :client-reverse-tags="clientReverseTags" />
                       <BalancersTab :template-settings="templateSettings" :client-reverse-tags="clientReverseTags" />
                     </a-tab-pane>
                     </a-tab-pane>
 
 
                     <a-tab-pane key="tpl-dns" class="tab-pane">
                     <a-tab-pane key="tpl-dns" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <DatabaseOutlined /> <span>DNS</span>
+                        <a-tooltip :title="isMobile ? 'DNS' : null">
+                          <DatabaseOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">DNS</span>
                       </template>
                       </template>
                       <DnsTab :template-settings="templateSettings" />
                       <DnsTab :template-settings="templateSettings" />
                     </a-tab-pane>
                     </a-tab-pane>
 
 
                     <a-tab-pane key="tpl-advanced" class="tab-pane">
                     <a-tab-pane key="tpl-advanced" class="tab-pane">
                       <template #tab>
                       <template #tab>
-                        <CodeOutlined /> <span>{{ t('pages.xray.advancedTemplate') }}</span>
+                        <a-tooltip :title="isMobile ? t('pages.xray.advancedTemplate') : null">
+                          <CodeOutlined />
+                        </a-tooltip>
+                        <span v-if="!isMobile">{{ t('pages.xray.advancedTemplate') }}</span>
                       </template>
                       </template>
                       <a-list-item-meta :title="t('pages.xray.Template')" :description="t('pages.xray.TemplateDesc')" />
                       <a-list-item-meta :title="t('pages.xray.Template')" :description="t('pages.xray.TemplateDesc')" />
                       <a-radio-group v-model:value="advSettings" button-style="solid"
                       <a-radio-group v-model:value="advSettings" button-style="solid"
@@ -450,4 +468,33 @@ onBeforeUnmount(() => {
   font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
   font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
   font-size: 12px;
   font-size: 12px;
 }
 }
+
+.icons-only :deep(.ant-tabs-nav) {
+  margin-bottom: 8px;
+}
+
+.icons-only :deep(.ant-tabs-nav-wrap) {
+  width: 100%;
+}
+
+.icons-only :deep(.ant-tabs-nav-list) {
+  display: flex;
+  width: 100%;
+}
+
+.icons-only :deep(.ant-tabs-tab) {
+  flex: 1 1 0;
+  justify-content: center;
+  margin: 0;
+  padding: 10px 0;
+}
+
+.icons-only :deep(.ant-tabs-tab .anticon) {
+  margin: 0;
+  font-size: 18px;
+}
+
+.icons-only :deep(.ant-tabs-nav-operations) {
+  display: none;
+}
 </style>
 </style>