kahosan / home-page

一个简洁的 NAS 导航页 & 主页

Home Page:https://home-page-kahosan.vercel.app/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

提一个小建议

Rexloong opened this issue · comments

首先说一下我的所有docker容器都在一个服务器上,包括home-page(映射80端口)
我在配置卡片地址的时候参考如下:"path": "地址" // 如 https://services.com/xxx,如果服务的域名和主页的域名相同,可以直接写 /xxx
下面是我在内网的使用场景:

假如我的服务器内网ip为192.168.1.100,我在浏览器访问192.168.1.100进入home-page界面,但是我的其他容器服务是访问同一ip的不同端口,我只能在卡片地址上写http://192.168.1.100:端口号。这样能正常跳转;但是如果我的服务器ip变动以后,就无法跳转了。比如我用zerotier的ip来访问我的home-page页面,我点击卡片就不能跳转。

我想在内网纯ip访问的时候配置卡片地址时增加一个只用填端口号的功能,这样我用任意ip地址(可能还有home-page的端口号)访问home-page后,能根据这个地址+卡片填写的端口号来访问我的容器服务。

commented

我理解你的需求了,有点特殊

你的内网没有做反代,全都是靠端口访问的。然后在填写指定的 IP 后,后续通过别的反代 IP 进入 home-page 就访问不了服务。
但这应该只是加一条路由的问题?比如 zerotier 里可以在 Managed Routes 加一条对 192.168.1.100 的映射。

确实可以像你说的那样,但是我有可能会把我的服务器放在其他路由器下(出差或者其他情况),那么分配的ip就会变动。我如果通过内网ip访问主页,比如192.168.100.1,如果我的卡片地址填/tmp或者tmp,那么就会跳转到192.168.100.1/tmp。这个应该是一个函数实现的拼接吧,我的想法是能不能加个if判断,如果识别到":"冒号,就替换成192.168.100.1:tmp,这样就可以在卡片上填写":端口号"来实现我的需求。

commented

这里的地址是直接赋给了 a 标签的 href 属性,我并不想在主干上直接修改这块地方。
针对你的需求我建议是 fork 一下,然后对这块的逻辑进行修改。我可以给你提供一些技术支持

<a href={path} className="text-center opacity-animation-3 relative color-inherit" target={newTab ? '_blank' : '_self'} rel="noreferrer">

我在const safeIcon = useIcon(icon);这行代码下添加了以下的逻辑:
const regex = /^(\d{1,3}.){3}\d{1,3}/\d+$/;
const replacedpath = regex.test(path) ? path.replace('/', ':') : path;
然后把 <a href={path} className="text-center opacity-animation-3 relative color-inherit" target={newTab ? '_blank' : '_self'} rel="noreferrer">里面的path替换成了replacedpath,麻烦大佬看看能不能实现我的需求

commented

你参考一下吧,地址填 :123 就会跳转到域名 + 端口
比如当前是 http://192.168.123.1 就会跳转到 http://192.168.123.1:123
只对 : 开头的地址生效

import EditCard from './edit-card';

import { useEffect, useState } from 'react';
import { useEdit } from 'src/hooks/use-edit';
import { useIcon } from 'src/hooks/use-icon';

import { useAtomValue } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import type { Service } from 'src/types/services';
import { useServices } from 'src/hooks/use-services';

import { isBrowser } from 'src/lib/utils';

// TODO 提到一个 lib 中的 settings
export const serviceNameUpperAtom = atomWithStorage<boolean>('home-page-service-name-upper', true);
export const serviceOpenWithNewTabAtom = atomWithStorage<boolean>('home-page-service-open-with-new-tab', false);

export default function ServiceCard(props: Service) {
  const { isEdit } = useEdit();
  const { handleDeleteService } = useServices();

  const isUpper = useAtomValue(serviceNameUpperAtom);
  const newTab = useAtomValue(serviceOpenWithNewTabAtom);

  const { name, description, icon, path } = props;

  const [_path, _setPath] = useState('');

  const safeIcon = useIcon(icon);

  const isPort = path.startsWith(':');

  useEffect(() => {
    if (isBrowser) {
      const host = window.location.origin.replace(/:\d+$/, '');
      if (isPort)
        _setPath(host + path);
      else
        _setPath(path);
    }
  }, [isPort, path]);

  return (
    <div className="m-2 flex">
      <div
        className="flex-1 p-3 rd-2 position-relative max-w-80 dark:bg-#1D1D1D bg-#E2E2E2"
      >
        <div onClick={() => handleDeleteService(name)} className={`absolute top-1.5 right--2 i-carbon-trash-can transition-all ${isEdit ? 'visible op-100' : 'invisible op-0'} cursor-pointer z999`} />
        <EditCard {...props} />
        <a
          href={_path}
          className="text-center opacity-animation-3 relative color-inherit"
          target={newTab ? '_blank' : '_self'}
          rel="noreferrer"
        >
          <div className="flex justify-center items-center">
            <div className={`i-carbon-${safeIcon} text-2xl mr-2`} />
            <p className="text-3.5 m-0">{isUpper ? name.toUpperCase() : name}</p>
          </div>
          <small className="mt-2 text-3 op-70 block">{description}</small>
        </a>
      </div>
    </div>
  );
}

感谢大佬!