Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
2588669
fix: 修复批量修改状态无效。
Webb-L Nov 10, 2024
40445f7
feat(视图&数据): 重构主机表组件以支持 Syncfusion DataGrid
Webb-L Feb 19, 2025
2669f0c
feat(数据): 支持MacOS修改Hosts文件。
Webb-L May 21, 2025
7202abc
feat(本地化): 添加国际化支持并新增中英文本地化文件
Webb-L Jun 8, 2025
28f37c2
feat(结构&功能): 初始化核心模块并新增主页面功能
Webb-L Jun 8, 2025
df6a10e
feat(视图): 新增简单主页面组件并优化文件读取逻辑
Webb-L Jun 30, 2025
b128809
feat(数据处理): 支持主机行内容实时更新并优化生成逻辑
Webb-L Jul 8, 2025
f53e93e
feat(视图&逻辑): 支持通过路径加载和保存主机文件
Webb-L Jul 9, 2025
9530643
feat(功能): 支持导出 Hosts 文件为 ZIP 格式
Webb-L Jul 9, 2025
2324fff
feat(服务器&国际化): 新增HTTP服务器功能和完整国际化支持
Webb-L Jul 10, 2025
0997231
feat(依赖): 添加HTTP服务器依赖项
Webb-L Jul 10, 2025
33cfb56
fix(API&国际化): 修复API路径参数名称和国际化字符串重复问题
Webb-L Jul 10, 2025
8118819
feat(组件化&网络检测): 重构服务器状态显示和二维码功能
Webb-L Jul 10, 2025
86ec1e5
feat(依赖): 添加网络检测和二维码生成依赖
Webb-L Jul 10, 2025
009e223
feat(UI): 优化主机文件选择对话框界面
Webb-L Jul 10, 2025
071d69f
feat(服务&系统集成): 添加systemd服务文件和安装脚本
Webb-L Jul 11, 2025
4d7fae8
feat(架构重构): 服务器页面重构为BLoC架构并添加附近设备功能
Webb-L Jul 11, 2025
b81703a
feat(依赖): 添加equatable和url_launcher依赖
Webb-L Jul 11, 2025
13bb5b9
feat(服务器&国际化): 完善服务器设置和主机文件选择功能
Webb-L Jul 11, 2025
13c642e
feat(UI&UX): 优化服务器状态卡片设计和主机文件选择体验
Webb-L Jul 12, 2025
9b3a347
fix(UI&国际化): 修复构建时状态错误并完善国际化支持
Webb-L Jul 12, 2025
3c1e9a1
Merge remote-tracking branch 'origin/feature/v1.8.0' into feature/v1.8.0
Webb-L Jul 13, 2025
c63569d
feat(UI): 优化页面安全区域布局和抽屉导航体验
Webb-L Jul 13, 2025
0b57384
feat(附近设备&UI): 添加设备发现功能和优化导航体验
Webb-L Jul 13, 2025
ca387b2
feat(附近设备&缓存): 优化设备UI设计并添加API缓存功能
Webb-L Jul 16, 2025
be41fbf
feat(依赖&构建): 升级Kotlin版本并添加网格布局依赖
Webb-L Jul 16, 2025
f12c44e
refactor(附近设备): 重构状态管理架构模仿HomeCubit模式
Webb-L Jul 16, 2025
607c5dc
refactor(UI): 更新抽屉导航以适配新的附近设备状态管理
Webb-L Jul 16, 2025
7e4c7d3
feat(远程设备&缓存): 实现远程设备hosts文件加载功能
Webb-L Jul 17, 2025
fdce8d9
refactor: 重构附近设备功能并移除设备缓存机制
Webb-L Jul 20, 2025
e34b786
feat: 实现host文件使用功能及优化相关逻辑
Webb-L Jul 20, 2025
1bfde2d
fix: 修复HomeDrawer中Provider查找错误及文件比较功能
Webb-L Jul 20, 2025
5071d41
feat: 优化文本编辑器滚动同步及选择范围处理
Webb-L Jul 21, 2025
ee502f3
feat: 实现hosts文件差异对比功能
Webb-L Jul 21, 2025
51924cf
feat: 实现设备API文档查看功能
Webb-L Jul 22, 2025
fa5e1ec
feat: 在附近设备卡片中集成API文档查看功能
Webb-L Jul 22, 2025
e1b08fb
refactor: 优化UI界面和修复多项功能问题
Webb-L Jul 22, 2025
4573200
fix: 修复设备缓存和国际化相关问题
Webb-L Jul 22, 2025
c348b0b
refactor: 重构项目结构并清理未使用代码
Webb-L Jul 24, 2025
566eb9c
chore: 删除不再使用的服务安装脚本和相关文件
Webb-L Jul 26, 2025
88ee3d6
fix: 修复文本编辑控制器在撤回操作时的处理问题
Webb-L Jul 26, 2025
f37891c
feat: 更新 hosts.desktop 文件元数据和桌面操作项
Webb-L Jul 26, 2025
16fe830
feat: 添加多平台打包配置文件
Webb-L Jul 26, 2025
0aa0e1d
feat: 配置Android签名和更新应用图标
Webb-L Jul 26, 2025
e825831
feat: 添加macOS DMG打包配置和优化PKG配置
Webb-L Jul 26, 2025
d1d9428
update icon
Webb-L Jul 27, 2025
818ef00
Merge remote-tracking branch 'origin/feature/v1.8.0' into feature/v1.8.0
Webb-L Jul 27, 2025
cc3e447
refactor: 重构应用架构并优化文件处理逻辑
Webb-L Jul 27, 2025
2b3bcc4
refactor: 移除 flutter_background 依赖并简化应用启动
Webb-L Jul 27, 2025
6d5e34f
feat: 添加键盘可见性检测和动态布局调整
Webb-L Jul 27, 2025
bf55c85
feat: 禁用自启动和安装后启动
Webb-L Jul 27, 2025
41827e7
feat: 禁用自启动和安装后启动
Webb-L Jul 27, 2025
ff3164d
feat: 禁用自启动和安装后启动
Webb-L Jul 27, 2025
343f7de
feat: 禁用自启动和安装后启动
Webb-L Jul 27, 2025
f7a65dc
feat: 更新图片资源和README文档
Webb-L Jul 27, 2025
10d2aee
refactor: 更新依赖包和代码优化
Webb-L Jul 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/flutter_web_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Install Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.3'
flutter-version: '3.32.8'
channel: 'stable'

- name: Build web
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/

# IntelliJ related
Expand Down Expand Up @@ -41,3 +43,8 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
/android/app/.cxx/

/macos/DerivedData/

/dist
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Hosts Editor 是一个使用 Flutter 开发的应用程序,旨在简化 Linux

## 特性

- **跨平台支持**:虽然目前只支持 Linux、Windows、Web 系统,但未来计划扩展到其他操作系统。
- **跨平台支持**:虽然目前只支持 Linux、Windows、MacOS、Web 系统,但未来计划扩展到其他操作系统。
- **直观的用户界面**:使用 Flutter 构建,提供流畅的用户体验。
- **实时预览**:在编辑 hosts 文件时,实时查看更改效果。
- **安全性**:确保对 hosts 文件的修改是安全的,避免不必要的错误。
Expand Down Expand Up @@ -35,4 +35,8 @@ hosts /etc/hosts

### 测试是否配置成功

![6.png](image/6.png)
![6.png](image/6.png)

### 导入导出

![7.png](image/7.png)
23 changes: 19 additions & 4 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ plugins {
id "dev.flutter.flutter-gradle-plugin"
}

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
namespace = "top.webb_l.hosts"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
// ndkVersion = flutter.ndkVersion

ndkVersion = "27.0.12077973"

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
Expand All @@ -19,6 +27,15 @@ android {
jvmTarget = JavaVersion.VERSION_1_8
}

signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "top.webb_l.hosts"
Expand All @@ -32,9 +49,7 @@ android {

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.debug
signingConfig = signingConfigs.release
}
}
}
Expand Down
71 changes: 47 additions & 24 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,45 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<!--
Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.

In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin.
-->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT" />

<data android:mimeType="text/plain" />
</intent>
</queries>

<application
android:label="hosts"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/ic_launcher"
android:label="hosts">
<service
android:name=".HostsVpnService"
android:enabled="true"
android:permission="android.permission.BIND_VPN_SERVICE"
android:exported="true" >
<intent-filter>
<action android:name="android.net.VpnService"/>
</intent-filter>
</service>

<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as

<!--
Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
to determine the Window background behind the Flutter UI.
-->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />

<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<!--
Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java
-->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.

In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
</manifest>
57 changes: 57 additions & 0 deletions android/app/src/main/java/top/webb_l/hosts/HostsVpnService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package top.webb_l.hosts

import android.content.Intent
import android.net.VpnService
import android.os.ParcelFileDescriptor
import android.util.Log
import java.io.FileInputStream
import java.io.FileOutputStream
import kotlin.concurrent.thread

class HostsVpnService : VpnService() {

private var vpnInterface: ParcelFileDescriptor? = null

override fun onDestroy() {
super.onDestroy()
// 清理资源
vpnInterface?.close()
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// 启动 VPN
startVpn()
return START_STICKY
}

private fun startVpn() {
// 配置 VPN
val builder = Builder()
builder.setSession("MyVPN")
.addAddress("10.0.0.2", 24) // VPN 地址
.addRoute("0.0.0.0", 0) // 路由

vpnInterface = builder.establish()

// 这里是处理网络流量的逻辑
// 你需要实现读取数据包、解析 DNS 请求、根据 hosts 文件进行重定向等
Log.e("TAG", "run: ${vpnInterface}")
val inputStream = FileInputStream(vpnInterface!!.fileDescriptor)
val outputStream = FileOutputStream(vpnInterface!!.fileDescriptor)

val buffer = ByteArray(32767)
thread {
while (true) {
// 读取数据包
val length = inputStream.read(buffer)
if (length > 0) {
// 处理数据包
// 这里可以添加 DNS 解析和 hosts 文件的处理逻辑
Log.e("TAG", "startVpn: ${String(buffer, 0, length)}", )
// 将数据包写回输出流
outputStream.write(buffer, 0, length)
}
}
}
}
}
26 changes: 25 additions & 1 deletion android/app/src/main/kotlin/top/webb_l/hosts/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
package top.webb_l.hosts

import android.content.Intent
import android.net.VpnService
import android.util.Log
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine

class MainActivity: FlutterActivity()
class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
val intent = VpnService.prepare(this)
startService(Intent(this, HostsVpnService::class.java))
Log.e("TAG", "configureFlutterEngine: ", )
// if (intent != null) {
// startActivityForResult(intent, 0)
// } else {
// onActivityResult(0, RESULT_OK, null)
// }
super.configureFlutterEngine(flutterEngine)
}


override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == RESULT_OK) {
startService(Intent(this, HostsVpnService::class.java))
}
super.onActivityResult(requestCode, resultCode, data)
}
}
Binary file modified android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10'
}
}
allprojects {
repositories {
google()
Expand Down
3 changes: 3 additions & 0 deletions android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
4 changes: 3 additions & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
4 changes: 2 additions & 2 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ pluginManagement {

plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
id "com.android.application" version '8.7.2' apply false
id "org.jetbrains.kotlin.android" version "1.8.10" apply false
}

include ":app"
Binary file modified image/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified image/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified image/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified image/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
Expand Down Expand Up @@ -484,7 +484,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
Expand Down
Loading