mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-20 18:51:28 +08:00
新增RemoteWebApp项目
This commit is contained in:
@@ -51,7 +51,7 @@ namespace Photino.Blazor
|
||||
app.Initialize(sp, RootComponents);
|
||||
return app;
|
||||
}
|
||||
public PhotinoBlazorApp Build(IServiceProvider serviceProvider = null)
|
||||
public PhotinoBlazorApp Build(IServiceProvider serviceProvider)
|
||||
{
|
||||
// register root components with DI container
|
||||
// Services.AddSingleton(RootComponents);
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<PluginVersion>10.9.40</PluginVersion>
|
||||
<ProPluginVersion>10.9.40</ProPluginVersion>
|
||||
<DefaultVersion>10.9.40</DefaultVersion>
|
||||
<PluginVersion>10.9.41</PluginVersion>
|
||||
<ProPluginVersion>10.9.41</ProPluginVersion>
|
||||
<DefaultVersion>10.9.41</DefaultVersion>
|
||||
<AuthenticationVersion>2.9.18</AuthenticationVersion>
|
||||
<SourceGeneratorVersion>10.9.18</SourceGeneratorVersion>
|
||||
<NET8Version>8.0.18</NET8Version>
|
||||
|
@@ -77,7 +77,7 @@ internal sealed class Program
|
||||
hybridApp.MainWindow.SetUseOsDefaultLocation(false);
|
||||
hybridApp.MainWindow.SetUseOsDefaultSize(false);
|
||||
hybridApp.MainWindow.SetSize(new System.Drawing.Size(1920, 1080));
|
||||
hybridApp.MainWindow.SetTitle("ThingsGateway.Hybrid");
|
||||
hybridApp.MainWindow.SetTitle("ThingsGateway.Debug.Photino");
|
||||
hybridApp.MainWindow.SetIconFile("favicon.ico");
|
||||
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.2">
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
@@ -103,12 +103,12 @@ internal sealed class Program
|
||||
var hybridApp = builder.Build(app.Services);
|
||||
|
||||
hybridApp.MainWindow.ContextMenuEnabled = false;
|
||||
hybridApp.MainWindow.DevToolsEnabled = true;
|
||||
hybridApp.MainWindow.DevToolsEnabled = false;
|
||||
hybridApp.MainWindow.GrantBrowserPermissions = true;
|
||||
hybridApp.MainWindow.SetUseOsDefaultLocation(false);
|
||||
hybridApp.MainWindow.SetUseOsDefaultSize(false);
|
||||
hybridApp.MainWindow.SetSize(new System.Drawing.Size(1920, 1080));
|
||||
hybridApp.MainWindow.SetTitle("ThingsGateway.Hybrid");
|
||||
hybridApp.MainWindow.SetTitle("ThingsGateway.Photino");
|
||||
hybridApp.MainWindow.SetIconFile("favicon.ico");
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, error) =>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||||
<title>ThingsGateway.Hybrid</title>
|
||||
<title>ThingsGateway.Photino</title>
|
||||
<base href="/" />
|
||||
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
|
61
src/ThingsGateway.RemoteWebApp/Program.cs
Normal file
61
src/ThingsGateway.RemoteWebApp/Program.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://thingsgateway.cn/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Photino.NET;
|
||||
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace ThingsGateway.Server;
|
||||
|
||||
internal sealed class Program
|
||||
{
|
||||
[STAThread]
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
//当前工作目录设为程序集的基目录
|
||||
System.IO.Directory.SetCurrentDirectory(AppContext.BaseDirectory);
|
||||
// 增加中文编码支持
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
|
||||
var doc = new XmlDocument();
|
||||
doc.Load("appsettings.xml");
|
||||
|
||||
string? url = doc.SelectSingleNode("/settings/urls")?.InnerText;
|
||||
string? title = doc.SelectSingleNode("/settings/windowTitle")?.InnerText;
|
||||
|
||||
var window = new PhotinoWindow();
|
||||
|
||||
window.Load(url); // 👈 直接加载远程地址
|
||||
|
||||
window.ContextMenuEnabled = false;
|
||||
window.DevToolsEnabled = false;
|
||||
window.GrantBrowserPermissions = true;
|
||||
window.SetUseOsDefaultLocation(false);
|
||||
window.SetUseOsDefaultSize(false);
|
||||
window.SetSize(new System.Drawing.Size(1920, 1080));
|
||||
window.SetTitle(title);
|
||||
window.SetIconFile("favicon.ico");
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, error) =>
|
||||
{
|
||||
};
|
||||
|
||||
window.WindowClosing += (sender, e) =>
|
||||
{
|
||||
|
||||
return false;
|
||||
};
|
||||
window.WaitForClose();
|
||||
Thread.Sleep(2000);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<Import Project="..\Version.props" />
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Photino.NET" Version="4.0.16" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!--<Content Include="..\ThingsGateway.Server\wwwroot\favicon.ico" Link="wwwroot\favicon.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\ThingsGateway.Server\wwwroot\favicon.png" Link="wwwroot\favicon.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>-->
|
||||
<Content Include="appsettings.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="favicon.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net9.0;</TargetFrameworks>
|
||||
<CustomTargetFramework>$(TargetFramework)</CustomTargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<OpenApiGenerateDocuments>false</OpenApiGenerateDocuments>
|
||||
<SatelliteResourceLanguages>zh-Hans;en-US</SatelliteResourceLanguages>
|
||||
<PublishReadyToRunComposite>true</PublishReadyToRunComposite>
|
||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||
<!--<PublishAot>true</PublishAot>-->
|
||||
<CETCompat>false</CETCompat>
|
||||
|
||||
<PublishAot>true</PublishAot>
|
||||
<DebugType>none</DebugType>
|
||||
<EmbedAllSources>false</EmbedAllSources>
|
||||
<EmitDebugInformation>false</EmitDebugInformation>
|
||||
|
||||
<!--动态适用GC-->
|
||||
<GarbageCollectionAdaptationMode>1</GarbageCollectionAdaptationMode>
|
||||
<!--使用工作站GC-->
|
||||
<!--<ServerGarbageCollection>true</ServerGarbageCollection>-->
|
||||
<!--<PlatformTarget>x86</PlatformTarget>-->
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</Project>
|
5
src/ThingsGateway.RemoteWebApp/appsettings.xml
Normal file
5
src/ThingsGateway.RemoteWebApp/appsettings.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<settings>
|
||||
<urls>http://localhost:5000</urls>
|
||||
<windowTitle>ThingsGateway.RemoteWebApp</windowTitle>
|
||||
</settings>
|
BIN
src/ThingsGateway.RemoteWebApp/favicon.ico
Normal file
BIN
src/ThingsGateway.RemoteWebApp/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
@@ -21,14 +21,36 @@
|
||||
<link rel="apple-touch-icon" href="favicon.png">
|
||||
<base href="/" />
|
||||
<title>ThingsGateway</title>
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
|
||||
@{
|
||||
#if !NET8_0
|
||||
}
|
||||
|
||||
<link rel="stylesheet" href=@(Assets[$"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css"]) />
|
||||
<link rel="stylesheet" href=@(Assets[$"_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css"]) />
|
||||
<link rel="stylesheet" href=@(Assets[$"_content/BootstrapBlazor/css/motronic.min.css"]) />
|
||||
<link rel="stylesheet" href=@(Assets[$"ThingsGateway.Server.styles.css"]) />
|
||||
<link rel="stylesheet" href=@(Assets[$"{WebsiteConst.DefaultResourceUrl}css/site.css"]) />
|
||||
<link rel="stylesheet" href=@(Assets[$"{WebsiteConst.DefaultResourceUrl}css/devui.css"]) />
|
||||
<ImportMap />
|
||||
|
||||
@{
|
||||
#else
|
||||
}
|
||||
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/motronic.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"ThingsGateway.Server.styles.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/site.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/devui.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
@{
|
||||
#endif
|
||||
}
|
||||
|
||||
@* <script src=@($"{WebsiteConst.DefaultResourceUrl}js/theme.js") type="module"></script><!-- 初始主题 --> *@
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/devui.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
|
||||
<link rel="manifest" href="./manifest.json" />
|
||||
<HeadOutlet @rendermode="new InteractiveServerRenderMode(false)" />
|
||||
</head>
|
||||
@@ -40,47 +62,13 @@
|
||||
|
||||
<BlazorReconnector @rendermode="new InteractiveServerRenderMode(false)" />
|
||||
|
||||
<script src=@($"_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js?v={this.GetType().Assembly.GetName().Version}")></script>
|
||||
<script src=@($"{WebsiteConst.DefaultResourceUrl}js/culture.js?v={this.GetType().Assembly.GetName().Version}")></script>
|
||||
<script src="_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js"></script>
|
||||
<script src=@($"{WebsiteConst.DefaultResourceUrl}js/culture.js")></script>
|
||||
<script src="_framework/blazor.web.js"></script>
|
||||
<!-- PWA Service Worker -->
|
||||
<script type="text/javascript">'serviceWorker' in navigator && navigator.serviceWorker.register('./service-worker.js')</script>
|
||||
|
||||
<script>
|
||||
let installPromptTriggered = false;
|
||||
|
||||
function getCookie(name) {
|
||||
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
|
||||
return match ? match[2] : null;
|
||||
}
|
||||
|
||||
function hasShownInstallPrompt() {
|
||||
return getCookie("tgPWAInstallPromptShown") === "true";
|
||||
}
|
||||
|
||||
function markInstallPromptShown() {
|
||||
document.cookie = "tgPWAInstallPromptShown=true; max-age=31536000; path=/";
|
||||
}
|
||||
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!hasShownInstallPrompt() && !installPromptTriggered) {
|
||||
installPromptTriggered = true;
|
||||
setTimeout(() => {
|
||||
e.prompt()
|
||||
.then(() => e.userChoice)
|
||||
.then(choiceResult => {
|
||||
markInstallPromptShown();
|
||||
})
|
||||
.catch(err => {
|
||||
});
|
||||
}, 2000); // 延迟 2 秒提示
|
||||
} else {
|
||||
// console.log("已提示过安装,不再弹出");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script src="pwa-install.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
10
src/ThingsGateway.Server/Layout/_Imports.razor
Normal file
10
src/ThingsGateway.Server/Layout/_Imports.razor
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
|
||||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
34
src/ThingsGateway.Server/wwwroot/pwa-install.js
Normal file
34
src/ThingsGateway.Server/wwwroot/pwa-install.js
Normal file
@@ -0,0 +1,34 @@
|
||||
let installPromptTriggered = false;
|
||||
|
||||
function getCookie(name) {
|
||||
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
|
||||
return match ? match[2] : null;
|
||||
}
|
||||
|
||||
function hasShownInstallPrompt() {
|
||||
return getCookie("tgPWAInstallPromptShown") === "true";
|
||||
}
|
||||
|
||||
function markInstallPromptShown() {
|
||||
document.cookie = "tgPWAInstallPromptShown=true; max-age=31536000; path=/";
|
||||
}
|
||||
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!hasShownInstallPrompt() && !installPromptTriggered) {
|
||||
installPromptTriggered = true;
|
||||
setTimeout(() => {
|
||||
e.prompt()
|
||||
.then(() => e.userChoice)
|
||||
.then(choiceResult => {
|
||||
markInstallPromptShown();
|
||||
})
|
||||
.catch(err => {
|
||||
// 可选错误处理
|
||||
});
|
||||
}, 2000); // 延迟 2 秒提示
|
||||
} else {
|
||||
// console.log("已提示过安装,不再弹出");
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user