Compare commits

...

8 Commits

85 changed files with 542 additions and 146 deletions

View File

@ -14,12 +14,43 @@ namespace HeartbeatSender
{ {
private readonly HttpClient httpClient = new HttpClient(); private readonly HttpClient httpClient = new HttpClient();
private string token; private string token;
private string heartbeatUrl; private string token_heartbeatUrl;
private string init_heartbeatUrl;
public heartbeatSender(string heartbeatUrl) public heartbeatSender()
{ {
this.heartbeatUrl = heartbeatUrl; LoadHeartbeatUrls("txt/HeartBeat.txt");
} }
/// <summary>
/// 讀取URL
/// </summary>
/// <param name="filePath">路徑</param>
private void LoadHeartbeatUrls(string filePath)
{
if (!File.Exists(filePath))
{
Console.WriteLine("找不到 HeartBeat.txt");
return;
}
string[] lines = File.ReadAllLines(filePath);
foreach (string line in lines)
{
if (line.StartsWith("init:"))
{
init_heartbeatUrl = line.Substring("init:".Length).Trim();
}
else if (line.StartsWith("token:"))
{
token_heartbeatUrl = line.Substring("token:".Length).Trim();
}
}
Console.WriteLine("init URL: " + init_heartbeatUrl);
Console.WriteLine("token URL: " + token_heartbeatUrl);
}
public static string GetLocalIPv4() public static string GetLocalIPv4()
{ {
foreach (var ip in Dns.GetHostEntry(Dns.GetHostName()).AddressList) foreach (var ip in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
@ -33,7 +64,8 @@ namespace HeartbeatSender
} }
public async Task<bool> LoginAndGetTokenAsync() public async Task<bool> LoginAndGetTokenAsync()
{ {
var loginUrl = "http://zqd.superstar.dnsnet.cc/api/room/receiveRegister"; // init_heartbeat
//var loginUrl = "http://zqd.superstar.dnsnet.cc/api/room/receiveRegister";
string hostName = System.Net.Dns.GetHostName(); string hostName = System.Net.Dns.GetHostName();
var loginPayload = new var loginPayload = new
@ -50,7 +82,7 @@ namespace HeartbeatSender
try try
{ {
var response = await httpClient.PostAsync(loginUrl, content); var response = await httpClient.PostAsync(init_heartbeatUrl, content);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
var responseJson = await response.Content.ReadAsStringAsync(); var responseJson = await response.Content.ReadAsStringAsync();
@ -97,8 +129,9 @@ namespace HeartbeatSender
var json = JsonSerializer.Serialize(heartbeatData); var json = JsonSerializer.Serialize(heartbeatData);
var content = new StringContent(json, Encoding.UTF8, "application/json"); var content = new StringContent(json, Encoding.UTF8, "application/json");
heartbeatUrl = "http://zqd.superstar.dnsnet.cc/api/room/heartbeat"; // token_heartbeat
var request = new HttpRequestMessage(HttpMethod.Post, heartbeatUrl); // heartbeatUrl = "http://zqd.superstar.dnsnet.cc/api/room/heartbeat";
var request = new HttpRequestMessage(HttpMethod.Post, token_heartbeatUrl);
request.Content = content; request.Content = content;
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
// Console.WriteLine("送出的 JSON"); // Console.WriteLine("送出的 JSON");

View File

@ -173,7 +173,7 @@ namespace DualScreenDemo
this.Controls.Add(yueYuButtonNewSong); this.Controls.Add(yueYuButtonNewSong);
yingWenButtonNewSong = new Button { Text = "英文2", Visible = false }; yingWenButtonNewSong = new Button {Visible = false };
ResizeAndPositionButton(yingWenButtonNewSong, 1214, 418, 209, 59); ResizeAndPositionButton(yingWenButtonNewSong, 1214, 418, 209, 59);
Rectangle yingWenNewSongButtonCropArea = new Rectangle(1214, 418, 209, 59); Rectangle yingWenNewSongButtonCropArea = new Rectangle(1214, 418, 209, 59);
@ -189,7 +189,7 @@ namespace DualScreenDemo
this.Controls.Add(yingWenButtonNewSong); this.Controls.Add(yingWenButtonNewSong);
riYuButtonNewSong = new Button { Text = "日語2", Visible = false }; riYuButtonNewSong = new Button { Visible = false };
ResizeAndPositionButton(riYuButtonNewSong, 1214, 481, 209, 59); ResizeAndPositionButton(riYuButtonNewSong, 1214, 481, 209, 59);
Rectangle riYuNewSongButtonCropArea = new Rectangle(1214, 481, 209, 59); Rectangle riYuNewSongButtonCropArea = new Rectangle(1214, 481, 209, 59);
@ -205,7 +205,7 @@ namespace DualScreenDemo
this.Controls.Add(riYuButtonNewSong); this.Controls.Add(riYuButtonNewSong);
hanYuButtonNewSong = new Button { Text = "韓語2", Visible = false }; hanYuButtonNewSong = new Button {Visible = false };
ResizeAndPositionButton(hanYuButtonNewSong, 1214, 544, 209, 58); ResizeAndPositionButton(hanYuButtonNewSong, 1214, 544, 209, 58);
Rectangle hanYuNewSongButtonCropArea = new Rectangle(1214, 544, 209, 58); Rectangle hanYuNewSongButtonCropArea = new Rectangle(1214, 544, 209, 58);

View File

@ -25,15 +25,15 @@ namespace DualScreenDemo
int[,] coords = new int[,] int[,] coords = new int[,]
{ {
{794, 508, 70, 65}, {794, 508, 70, 65},
{878, 508, 70, 65}, {873, 508, 70, 65},
{962, 508, 70, 65}, {952, 508, 70, 65},
{1046, 508, 70, 65}, {1031, 508, 70, 65},
{1130, 508, 70, 65}, {1110, 508, 70, 65},
{794, 580, 70, 65}, {794, 580, 70, 65},
{878, 580, 70, 65}, {873, 580, 70, 65},
{962, 580, 70, 65}, {952, 580, 70, 65},
{1046, 580, 70, 65}, {1031, 580, 70, 65},
{1130, 580, 70, 65} {1110, 580, 70, 65}
}; };
int screenW = Screen.PrimaryScreen.Bounds.Width; int screenW = Screen.PrimaryScreen.Bounds.Width;
@ -53,7 +53,7 @@ namespace DualScreenDemo
string fileName = (i + 2).ToString("00"); string fileName = (i + 2).ToString("00");
string filePath = Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-" + fileName + ".jpg"); string filePath = Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-" + fileName + ".png");
favoriteNumberButton[i].BackgroundImage = Image.FromFile(filePath); favoriteNumberButton[i].BackgroundImage = Image.FromFile(filePath);
favoriteNumberButton[i].BackgroundImageLayout = ImageLayout.Stretch; favoriteNumberButton[i].BackgroundImageLayout = ImageLayout.Stretch;
favoriteNumberButton[i].FlatStyle = FlatStyle.Flat; favoriteNumberButton[i].FlatStyle = FlatStyle.Flat;
@ -85,7 +85,7 @@ namespace DualScreenDemo
Name = "enterFavoriteButton" Name = "enterFavoriteButton"
}; };
ResizeAndPositionButton(enterFavoriteButton, 832, 657, 70, 65); ResizeAndPositionButton(enterFavoriteButton, 832, 657, 70, 65);
enterFavoriteButton.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-12.jpg")); enterFavoriteButton.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-12.png"));
enterFavoriteButton.BackgroundImageLayout = ImageLayout.Stretch; enterFavoriteButton.BackgroundImageLayout = ImageLayout.Stretch;
enterFavoriteButton.FlatStyle = FlatStyle.Flat; enterFavoriteButton.FlatStyle = FlatStyle.Flat;
enterFavoriteButton.FlatAppearance.BorderSize = 0; enterFavoriteButton.FlatAppearance.BorderSize = 0;
@ -100,7 +100,7 @@ namespace DualScreenDemo
Name = "newFavoriteButton" Name = "newFavoriteButton"
}; };
ResizeAndPositionButton(newFavoriteButton, 916, 657, 70, 65); ResizeAndPositionButton(newFavoriteButton, 916, 657, 70, 65);
newFavoriteButton.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-13.jpg")); newFavoriteButton.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-13.png"));
newFavoriteButton.BackgroundImageLayout = ImageLayout.Stretch; newFavoriteButton.BackgroundImageLayout = ImageLayout.Stretch;
newFavoriteButton.FlatStyle = FlatStyle.Flat; newFavoriteButton.FlatStyle = FlatStyle.Flat;
newFavoriteButton.FlatAppearance.BorderSize = 0; newFavoriteButton.FlatAppearance.BorderSize = 0;
@ -115,7 +115,7 @@ namespace DualScreenDemo
Name = "refillFavoriteButton" Name = "refillFavoriteButton"
}; };
ResizeAndPositionButton(refillFavoriteButton, 999, 657, 70, 65); ResizeAndPositionButton(refillFavoriteButton, 999, 657, 70, 65);
refillFavoriteButton.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-14.jpg")); refillFavoriteButton.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-14.png"));
refillFavoriteButton.BackgroundImageLayout = ImageLayout.Stretch; refillFavoriteButton.BackgroundImageLayout = ImageLayout.Stretch;
refillFavoriteButton.FlatStyle = FlatStyle.Flat; refillFavoriteButton.FlatStyle = FlatStyle.Flat;
refillFavoriteButton.FlatAppearance.BorderSize = 0; refillFavoriteButton.FlatAppearance.BorderSize = 0;
@ -130,7 +130,7 @@ namespace DualScreenDemo
Name = "closeFavoriteButton" Name = "closeFavoriteButton"
}; };
ResizeAndPositionButton(closeFavoriteButton, 1083, 657, 70, 65); ResizeAndPositionButton(closeFavoriteButton, 1083, 657, 70, 65);
closeFavoriteButton.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-15.jpg")); closeFavoriteButton.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛-15.png"));
closeFavoriteButton.BackgroundImageLayout = ImageLayout.Stretch; closeFavoriteButton.BackgroundImageLayout = ImageLayout.Stretch;
closeFavoriteButton.FlatStyle = FlatStyle.Flat; closeFavoriteButton.FlatStyle = FlatStyle.Flat;
closeFavoriteButton.FlatAppearance.BorderSize = 0; closeFavoriteButton.FlatAppearance.BorderSize = 0;
@ -349,7 +349,7 @@ namespace DualScreenDemo
if (!FavoritePictureBox.Visible) if (!FavoritePictureBox.Visible)
{ {
ShowImageOnFavoritePictureBox(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛_工作區域.jpg")); ShowImageOnFavoritePictureBox(Path.Combine(Application.StartupPath, @"themes\superstar\我的最愛\我的最愛_工作區域.png"));
SetFavoritePictureBoxAndButtonsVisibility(true); SetFavoritePictureBoxAndButtonsVisibility(true);
} }
else else
@ -399,14 +399,27 @@ namespace DualScreenDemo
FavoritePictureBox.Image = image; FavoritePictureBox.Image = image;
// 設定 PictureBox 的大小與位置(依你的需要調整) // 設定 PictureBox 的大小與位置(依你的需要調整)
ResizeAndPositionPictureBox(FavoritePictureBox, 773, 380, (int)(image.Width * 0.8f) , (int)(image.Height * 0.8f)); // ResizeAndPositionPictureBox(FavoritePictureBox, 773, 380, image.Width , image.Height);
// ResizeAndPositionPictureBox(FavoritePictureBox, 773, 380, (int)(image.Width * 0.8f) , (int)(image.Height * 0.8f));
// 不要用 ResizeAndPositionPictureBox 這東西是static 他會導致其他東西顯示錯誤
int screenW = Screen.PrimaryScreen.Bounds.Width;
int screenH = Screen.PrimaryScreen.Bounds.Height;
float widthRatio = screenW / (float)1440;
float heightRatio = screenH / (float)900;
FavoritePictureBox.Location = new Point(
(int)(773 * widthRatio),
(int)(380 * heightRatio)
);
FavoritePictureBox.Size = new Size(
(int)(image.Width * widthRatio),
(int)(image.Height * heightRatio)
);
}
FavoritePictureBox.Visible = true; FavoritePictureBox.Visible = true;
}
else
{
Console.WriteLine("圖片檔案不存在:" + imagePath);
}
} }

View File

@ -11,7 +11,7 @@ namespace DualScreenDemo
try try
{ {
string imagePath = Path.Combine(Application.StartupPath, "themes/superstar/cropped_qrcode.jpg"); string imagePath = Path.Combine(Application.StartupPath, "themes/superstar/cropped_qrcode.png");
if (!File.Exists(imagePath)) if (!File.Exists(imagePath))
{ {
Console.WriteLine("Base image not found: " + imagePath); Console.WriteLine("Base image not found: " + imagePath);
@ -79,8 +79,10 @@ namespace DualScreenDemo
{ {
using (Graphics g = Graphics.FromImage(bitmap)) using (Graphics g = Graphics.FromImage(bitmap))
{ {
g.DrawImage(baseImage, 0, 0); // g.DrawImage(baseImage, 0, 0);
// cropped qrcode 版型不同設定調整
g.DrawImage(baseImage, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
Rectangle qrCodeRect = new Rectangle(32, 39, 165, 165); Rectangle qrCodeRect = new Rectangle(32, 39, 165, 165);
g.DrawImage(qrCodeImage, qrCodeRect); g.DrawImage(qrCodeImage, qrCodeRect);
@ -94,7 +96,7 @@ namespace DualScreenDemo
ResizeAndPositionControl(pictureBoxQRCode, 975, 442, 226, 274); ResizeAndPositionControl(pictureBoxQRCode, 975, 442, 226, 274);
Bitmap originalImage = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\cropped_qrcode.jpg")); Bitmap originalImage = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\cropped_qrcode.png"));
Rectangle closeQRCodeCropArea = new Rectangle(198, 6, 22, 22); Rectangle closeQRCodeCropArea = new Rectangle(198, 6, 22, 22);

View File

@ -236,14 +236,15 @@ namespace DualScreenDemo{
isLoggedIn=false; isLoggedIn=false;
userPhone=string.Empty; userPhone=string.Empty;
} }
private static int countforSearch = 0; //private static int countforSearch = 0;
private static void writeLogforSearchTime(long elapsedMs){ private static void writeLogforSearchTime(long elapsedMs){
/*
countforSearch++; countforSearch++;
string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "txt", "searchTimeLog.txt"); string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "txt", "searchTimeLog.txt");
string data = $"{countforSearch}, {elapsedMs} " + Environment.NewLine; string data = $"{countforSearch}, {elapsedMs} " + Environment.NewLine;
File.AppendAllText(logFilePath, data); File.AppendAllText(logFilePath, data);
*/
} }
public void AddSongCount(string id){ public void AddSongCount(string id){

View File

@ -15,6 +15,7 @@ namespace DualScreenDemo
{ {
if (currentSequence[currentSequence.Count - 1] != correctSequence[currentSequence.Count - 1]) if (currentSequence[currentSequence.Count - 1] != correctSequence[currentSequence.Count - 1])
{ {
Console.WriteLine(currentSequence[currentSequence.Count - 1] +" 比對 " + correctSequence[currentSequence.Count - 1] +" 順序錯誤,重置序列");
// 順序錯誤,重置序列 // 順序錯誤,重置序列
currentSequence.Clear(); currentSequence.Clear();
return; return;
@ -26,16 +27,23 @@ namespace DualScreenDemo
{ {
try try
{ {
// 使用 Windows 命令關機 // ✅ 這行要在主執行緒執行,避免 UI 錯誤
System.Diagnostics.Process.Start("shutdown", "/s /t 0"); Cursor.Show();
Console.WriteLine("使用 Windows 命令關機");
// ✅ 關機動作移到背景執行緒
new System.Threading.Thread(() =>
{
System.Diagnostics.Process.Start("shutdown", "/s /t 0");
}).Start();
} }
catch (Exception ex) catch (Exception ex)
{ {
MessageBox.Show($"關機失敗: {ex.Message}"); MessageBox.Show($"關機失敗: {ex.Message}");
// 如果關機失敗,退出程式
Application.Exit();
} }
} }
} }
} }
} }

View File

@ -336,21 +336,25 @@ namespace DualScreenDemo
} }
private void buttonMiddle_Click(object sender, EventArgs e) private void buttonMiddle_Click(object sender, EventArgs e)
{ {
Console.WriteLine("巨");
sequenceManager.ProcessClick("巨"); sequenceManager.ProcessClick("巨");
} }
private void buttonTopRight_Click(object sender, EventArgs e) private void buttonTopRight_Click(object sender, EventArgs e)
{ {
Console.WriteLine("級");
sequenceManager.ProcessClick("級"); sequenceManager.ProcessClick("級");
} }
private void buttonTopLeft_Click(object sender, EventArgs e) private void buttonTopLeft_Click(object sender, EventArgs e)
{ {
Console.WriteLine("超");
sequenceManager.ProcessClick("超"); sequenceManager.ProcessClick("超");
} }
private void buttonThanks_Click(object sender, EventArgs e) private void buttonThanks_Click(object sender, EventArgs e)
{ {
Console.WriteLine("星");
sequenceManager.ProcessClick("星"); sequenceManager.ProcessClick("星");
} }
@ -1372,12 +1376,12 @@ namespace DualScreenDemo
TraditionalChineseButton_Click TraditionalChineseButton_Click
); );
/* 關閉應用程式按鈕*/
exitButton = new Button{}; exitButton = new Button{};
exitButton.Name = "exitButton"; /*exitButton.Name = "exitButton";
ConfigureButton(exitButton, 1394, 2, 1428 - 1394, 37 - 2, ConfigureButton(exitButton, 1394, 2, 1428 - 1394, 37 - 2,
resizedNormalStateImage, resizedMouseOverImage, resizedMouseDownImage, resizedNormalStateImage, resizedMouseOverImage, resizedMouseDownImage,
(sender, e) => Application.Exit()); (sender, e) => Application.Exit());*/
} }
private void InitializeButton(ref Button button, ref Bitmap normalBackground, ref Bitmap activeBackground, string buttonName, int x, int y, int width, int height, string imagePath, EventHandler clickEventHandler) private void InitializeButton(ref Button button, ref Bitmap normalBackground, ref Bitmap activeBackground, string buttonName, int x, int y, int width, int height, string imagePath, EventHandler clickEventHandler)
@ -1533,12 +1537,25 @@ namespace DualScreenDemo
try try
{ {
// 1. 檢查是否能連接到 SVR01 // 1. 檢查是否能連接到 SVR01
string serverVideoPath = @"\\SVR01\SuperstarB\video"; string serverVideoPath = @"\\SVR01\video";
string localVideoPath = @"C:\video"; string serverVideoPath2 = @"\\SVR02\video";
string selectedServerPath = null;
if (!Directory.Exists(serverVideoPath)) string localVideoPath = @"D:\video";
if (Directory.Exists(serverVideoPath))
{ {
Console.WriteLine("未連接到SVR使用本地影片"); selectedServerPath = serverVideoPath;
Console.WriteLine("已連接到 SVR01");
}
else if (Directory.Exists(serverVideoPath2))
{
selectedServerPath = serverVideoPath2;
Console.WriteLine("已連接到 SVR02");
}
else
{
Console.WriteLine("未連接到 SVR使用本地影片");
LoadLocalVideoFiles(); LoadLocalVideoFiles();
return; return;
} }
@ -1550,7 +1567,7 @@ namespace DualScreenDemo
} }
// 獲取服務器和本地的所有文件 // 獲取服務器和本地的所有文件
var serverFiles = Directory.GetFiles(serverVideoPath, "*.mpg") var serverFiles = Directory.GetFiles(selectedServerPath, "*.mpg")
.Select(f => new FileInfo(f)) .Select(f => new FileInfo(f))
.ToDictionary(f => f.Name, f => f); .ToDictionary(f => f.Name, f => f);
@ -1606,7 +1623,7 @@ namespace DualScreenDemo
{ {
try try
{ {
string videoDirectory = @"C:\video\"; string videoDirectory = @"D:\video\";
string[] videoFiles = Directory.GetFiles(videoDirectory, "*.mpg"); string[] videoFiles = Directory.GetFiles(videoDirectory, "*.mpg");
string pattern = @"^(?<songNumber>\d+)-.*?-(?<songName>[^-]+)-"; string pattern = @"^(?<songNumber>\d+)-.*?-(?<songName>[^-]+)-";
@ -1880,7 +1897,7 @@ namespace DualScreenDemo
string songInfo = songData.Song ?? "未提供歌曲信息"; string songInfo = songData.Song ?? "未提供歌曲信息";
g.DrawString(songInfo, font, textBrush, new PointF(201, 29)); g.DrawString(songInfo, font, textBrush, new PointF(73, 8));
} }
ResizeAndPositionPictureBox(VodScreenPictureBox, xPosition, yPosition, pictureBoxWidth, pictureBoxHeight); ResizeAndPositionPictureBox(VodScreenPictureBox, xPosition, yPosition, pictureBoxWidth, pictureBoxHeight);
@ -2137,19 +2154,21 @@ namespace DualScreenDemo
/// <summary> /// <summary>
/// 重置所有輸入框 /// 重置所有輸入框
/// </summary> /// </summary>
private void ResetinputBox(){ private void ResetinputBox()
inputBoxZhuYinSingers.Text = ""; {
inputBoxZhuYinSongs.Text = ""; inputBoxZhuYinSingers?.Clear();
inputBoxEnglishSingers.Text = ""; inputBoxZhuYinSongs?.Clear();
inputBoxEnglishSongs.Text = ""; inputBoxEnglishSingers?.Clear();
inputBoxPinYinSingers.Text = ""; inputBoxEnglishSongs?.Clear();
inputBoxPinYinSongs.Text = ""; inputBoxPinYinSingers?.Clear();
inputBoxWordCountSingers.Text = ""; inputBoxPinYinSongs?.Clear();
inputBoxWordCountSongs.Text = ""; inputBoxWordCountSingers?.Clear();
inputBoxSongIDSearch.Text = ""; inputBoxWordCountSongs?.Clear();
handwritingInputBoxForSongs.Text = ""; inputBoxSongIDSearch?.Clear();
handwritingInputBoxForSingers.Text = ""; handwritingInputBoxForSongs?.Clear();
handwritingInputBoxForSingers?.Clear();
} }
private void MuteUnmuteButton_Click(object sender, EventArgs e) private void MuteUnmuteButton_Click(object sender, EventArgs e)
{ {
@ -2521,11 +2540,12 @@ namespace DualScreenDemo
if (initialState.Equals("CLOSE", StringComparison.OrdinalIgnoreCase)) if (initialState.Equals("CLOSE", StringComparison.OrdinalIgnoreCase))
{ {
/*
foreach (Control ctrl in this.Controls) foreach (Control ctrl in this.Controls)
{ {
ctrl.Enabled = false; ctrl.Enabled = false;
} }
*/
ShowSendOffScreen(); ShowSendOffScreen();
} }
} }

View File

@ -81,7 +81,8 @@ namespace DualScreenDemo
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
// 設定檔路徑 // 設定檔路徑
string iniFilePath = "config.ini"; string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data; IniData data;
@ -107,7 +108,8 @@ namespace DualScreenDemo
private IniData LoadConfigData() private IniData LoadConfigData()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
string iniFilePath = "config.ini"; string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
// 使用 UTF-8 讀取 INI 檔案並解析內容 // 使用 UTF-8 讀取 INI 檔案並解析內容
using (var reader = new StreamReader(iniFilePath, Encoding.UTF8)) using (var reader = new StreamReader(iniFilePath, Encoding.UTF8))
@ -635,7 +637,8 @@ namespace DualScreenDemo
{ {
// 創建 INI 解析器 // 創建 INI 解析器
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
string iniFilePath = "config.ini"; // 配置文件的路徑 string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data; IniData data;
// 打開並讀取配置文件 // 打開並讀取配置文件
@ -681,7 +684,8 @@ namespace DualScreenDemo
private void LoadPictureBoxZhuYinSingerCoordsFromConfig() private void LoadPictureBoxZhuYinSingerCoordsFromConfig()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
IniData data = parser.ReadFile("config.ini"); string iniPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data = parser.ReadFile(iniPath);
var coords = data["PictureBoxZhuYinSingers"]; var coords = data["PictureBoxZhuYinSingers"];
pictureBoxZhuYinSingerCoords = ( pictureBoxZhuYinSingerCoords = (

View File

@ -52,7 +52,9 @@ namespace DualScreenDemo
private void LoadNumberButtonCoordsFromConfig() private void LoadNumberButtonCoordsFromConfig()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
IniData data = parser.ReadFile("config.ini"); string iniPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data = parser.ReadFile(iniPath);
var buttonList = new List<(int X, int Y, int Width, int Height)>(); var buttonList = new List<(int X, int Y, int Width, int Height)>();
@ -398,12 +400,18 @@ namespace DualScreenDemo
clearButtonEnglishSingers.Visible = isVisible; clearButtonEnglishSingers.Visible = isVisible;
if (isVisible) clearButtonEnglishSingers.BringToFront(); if (isVisible) clearButtonEnglishSingers.BringToFront();
} }
if (closeButtonEnglishSingers != null)
{
closeButtonEnglishSingers.Visible = isVisible;
if (isVisible) closeButtonEnglishSingers.BringToFront();
}
closeButtonEnglishSingers.Visible = isVisible; if (inputBoxEnglishSingers != null)
if (isVisible) closeButtonEnglishSingers.BringToFront(); {
inputBoxEnglishSingers.Visible = isVisible;
inputBoxEnglishSingers.Visible = isVisible; if (isVisible) inputBoxEnglishSingers.BringToFront();
if (isVisible) inputBoxEnglishSingers.BringToFront(); }
ResumeLayout(); ResumeLayout();
PerformLayout(); PerformLayout();
@ -416,10 +424,10 @@ namespace DualScreenDemo
} }
modifyButtonEnglishSingers.Refresh(); if (modifyButtonEnglishSingers != null) modifyButtonEnglishSingers.Refresh();
clearButtonEnglishSingers.Refresh(); if (clearButtonEnglishSingers != null) clearButtonEnglishSingers.Refresh();
closeButtonEnglishSingers.Refresh(); if (closeButtonEnglishSingers != null) closeButtonEnglishSingers.Refresh();
inputBoxEnglishSingers.Refresh(); if (inputBoxEnglishSingers != null) inputBoxEnglishSingers.Refresh();
}; };
if (this.InvokeRequired) if (this.InvokeRequired)

View File

@ -252,7 +252,9 @@ namespace DualScreenDemo
private void LoadPictureBoxPinYinSingerCoordsFromConfig() private void LoadPictureBoxPinYinSingerCoordsFromConfig()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
IniData data = parser.ReadFile("config.ini"); string iniPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data = parser.ReadFile(iniPath);
var coords = data["PictureBoxPinYinSingers"]; var coords = data["PictureBoxPinYinSingers"];
pictureBoxPinYinSingerCoords = ( pictureBoxPinYinSingerCoords = (

View File

@ -99,7 +99,8 @@ namespace DualScreenDemo
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
// 設定檔路徑 // 設定檔路徑
string iniFilePath = "config.ini"; string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data; IniData data;
@ -125,7 +126,8 @@ namespace DualScreenDemo
private IniData LoadConfigDataforWordCountSingers() private IniData LoadConfigDataforWordCountSingers()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
string iniFilePath = "config.ini"; string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
// 使用 UTF-8 讀取 INI 檔案並解析內容 // 使用 UTF-8 讀取 INI 檔案並解析內容
using (var reader = new StreamReader(iniFilePath, Encoding.UTF8)) using (var reader = new StreamReader(iniFilePath, Encoding.UTF8))
@ -636,7 +638,8 @@ namespace DualScreenDemo
{ {
// 創建 INI 解析器 // 創建 INI 解析器
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
string iniFilePath = "config.ini"; // 配置文件的路徑 string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data; IniData data;
// 打開並讀取配置文件 // 打開並讀取配置文件
@ -682,7 +685,8 @@ namespace DualScreenDemo
private void LoadPictureBoxWordCountSingerCoordsFromConfig() private void LoadPictureBoxWordCountSingerCoordsFromConfig()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
IniData data = parser.ReadFile("config.ini"); string iniPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data = parser.ReadFile(iniPath);
var coords = data["PictureBoxWordCountSingers"]; var coords = data["PictureBoxWordCountSingers"];
pictureBoxWordCountSingerCoords = ( pictureBoxWordCountSingerCoords = (

View File

@ -378,7 +378,9 @@ namespace DualScreenDemo
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
// 讀取 config.ini 設定檔的內容 // 讀取 config.ini 設定檔的內容
IniData data = parser.ReadFile("config.ini"); string iniPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data = parser.ReadFile(iniPath);
// 取得 "PictureBoxZhuYinSongs" 段落的設定數據 // 取得 "PictureBoxZhuYinSongs" 段落的設定數據
var coords = data["PictureBoxZhuYinSongs"]; var coords = data["PictureBoxZhuYinSongs"];

View File

@ -102,7 +102,8 @@ namespace DualScreenDemo
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
// 設定檔路徑 // 設定檔路徑
string iniFilePath = "config.ini"; string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data; IniData data;
@ -128,7 +129,8 @@ namespace DualScreenDemo
private IniData LoadConfigDataforSongIDSearch() private IniData LoadConfigDataforSongIDSearch()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
string iniFilePath = "config.ini"; string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
// 使用 UTF-8 讀取 INI 檔案並解析內容 // 使用 UTF-8 讀取 INI 檔案並解析內容
using (var reader = new StreamReader(iniFilePath, Encoding.UTF8)) using (var reader = new StreamReader(iniFilePath, Encoding.UTF8))
@ -647,7 +649,8 @@ namespace DualScreenDemo
{ {
// 創建 INI 解析器 // 創建 INI 解析器
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
string iniFilePath = "config.ini"; // 配置文件的路徑 string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data; IniData data;
// 打開並讀取配置文件 // 打開並讀取配置文件
@ -693,7 +696,9 @@ namespace DualScreenDemo
private void LoadPictureBoxSongIDSongCoordsFromConfig() private void LoadPictureBoxSongIDSongCoordsFromConfig()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
IniData data = parser.ReadFile("config.ini"); string iniPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data = parser.ReadFile(iniPath);
var coords = data["PictureBoxSongIDSearch"]; var coords = data["PictureBoxSongIDSearch"];
pictureBoxSongIDSongCoords = ( pictureBoxSongIDSongCoords = (

View File

@ -375,7 +375,9 @@ namespace DualScreenDemo
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
// 讀取 config.ini 文件並解析成 IniData 對象 // 讀取 config.ini 文件並解析成 IniData 對象
IniData data = parser.ReadFile("config.ini"); string iniPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data = parser.ReadFile(iniPath);
// 取得 PictureBoxPinYinSongs 區段的設定值 // 取得 PictureBoxPinYinSongs 區段的設定值
var coords = data["PictureBoxPinYinSongs"]; var coords = data["PictureBoxPinYinSongs"];

View File

@ -68,7 +68,8 @@ namespace DualScreenDemo
private IniData LoadConfigDataforWordCountSongs() private IniData LoadConfigDataforWordCountSongs()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
string iniFilePath = "config.ini"; string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
// 使用 UTF-8 讀取 INI 檔案並解析內容 // 使用 UTF-8 讀取 INI 檔案並解析內容
using (var reader = new StreamReader(iniFilePath, Encoding.UTF8)) using (var reader = new StreamReader(iniFilePath, Encoding.UTF8))
@ -579,7 +580,8 @@ namespace DualScreenDemo
{ {
// 創建 INI 解析器 // 創建 INI 解析器
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
string iniFilePath = "config.ini"; // 配置文件的路徑 string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data; IniData data;
// 打開並讀取配置文件 // 打開並讀取配置文件
@ -625,7 +627,9 @@ namespace DualScreenDemo
private void LoadPictureBoxWordCountSongCoordsFromConfig() private void LoadPictureBoxWordCountSongCoordsFromConfig()
{ {
var parser = new FileIniDataParser(); var parser = new FileIniDataParser();
IniData data = parser.ReadFile("config.ini"); string iniPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
IniData data = parser.ReadFile(iniPath);
var coords = data["PictureBoxWordCountSongs"]; var coords = data["PictureBoxWordCountSongs"];
pictureBoxWordCountSongCoords = ( pictureBoxWordCountSongCoords = (

View File

@ -17,8 +17,15 @@ namespace DualScreenDemo
[STAThread] [STAThread]
static void Main() static void Main()
{ {
Console.WriteLine("隱藏滑鼠游標");
Cursor.Hide();
AppDomain.CurrentDomain.ProcessExit += (s, e) =>
{
Cursor.Show();
};
Console.WriteLine("正在與中控取得聯繫"); Console.WriteLine("正在與中控取得聯繫");
var sender = new HeartbeatSender.heartbeatSender("http://zqd.superstar.dnsnet.cc/api/room/receiveRegister"); var sender = new HeartbeatSender.heartbeatSender();
// 同步呼叫非同步登入取得 token // 同步呼叫非同步登入取得 token
bool loginSuccess = sender.LoginAndGetTokenAsync().GetAwaiter().GetResult(); bool loginSuccess = sender.LoginAndGetTokenAsync().GetAwaiter().GetResult();
@ -181,7 +188,7 @@ namespace DualScreenDemo
{ {
if (primaryForm.videoPlayerForm == null) if (primaryForm.videoPlayerForm == null)
{ {
var filePath = @"C:\\video\\100015-周杰倫&aMei-不該-國語-vL-100-11000001.mpg"; var filePath = @"D:\\video\\100015-周杰倫&aMei-不該-國語-vL-100-11000001.mpg";
if (File.Exists(filePath)) if (File.Exists(filePath))
{ {
Screen secondaryScreen = Screen.AllScreens.FirstOrDefault(s => !s.Primary); Screen secondaryScreen = Screen.AllScreens.FirstOrDefault(s => !s.Primary);

View File

@ -38,7 +38,7 @@ Once the application is built, you can run it using the following steps:
2. **Execute the application**: 2. **Execute the application**:
```sh ```sh
superstar_1.0.0.exe superstar_1.1.0.exe
``` ```
## Configuration ## Configuration

View File

@ -90,16 +90,16 @@ namespace DualScreenDemo
string stateFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"txt","states.txt"); string stateFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"txt","states.txt");
string initialState = ReadStateFile(stateFilePath); string initialState = ReadStateFile(stateFilePath);
/*
if (initialState.Equals("CLOSE", StringComparison.OrdinalIgnoreCase)) if (initialState.Equals("CLOSE", StringComparison.OrdinalIgnoreCase))
{ {
_ = SafeInvoke(PrimaryForm.Instance, () => _ = SafeInvoke(PrimaryForm.Instance, () =>
{ {
try { try {
foreach (Control ctrl in PrimaryForm.Instance.Controls) /*foreach (Control ctrl in PrimaryForm.Instance.Controls)
{ {
ctrl.Enabled = false; ctrl.Enabled = false;
} }*/
PrimaryForm.Instance.ShowSendOffScreen(); PrimaryForm.Instance.ShowSendOffScreen();
} }
catch (Exception ex) { catch (Exception ex) {
@ -107,7 +107,7 @@ namespace DualScreenDemo
} }
}); });
} }
*/
while (true) while (true)
{ {
@ -150,14 +150,9 @@ namespace DualScreenDemo
await SafeInvoke(PrimaryForm.Instance, async () => await SafeInvoke(PrimaryForm.Instance, async () =>
{ {
PrimaryForm.Instance.ShowSendOffScreen(); PrimaryForm.Instance.ShowSendOffScreen();
_ = SafeInvoke(PrimaryForm.Instance, () =>
{
string marqueeMessage= "歡迎使用超級巨星歡唱網路版系統,與你共度美好時光。";
OverlayForm.MainForm.UpdateMarqueeText(marqueeMessage, OverlayForm.MarqueeStartPosition.Middle, Color.White);
});
Console.WriteLine("開始設置新的播放列表"); Console.WriteLine("開始設置新的播放列表");
string closePath = @"C:\video\CLOSE.MPG"; string closePath = @"D:\video\CLOSE.MPG";
if (File.Exists(closePath)) if (File.Exists(closePath))
{ {
SongData closeSong = new SongData( SongData closeSong = new SongData(
@ -212,12 +207,6 @@ namespace DualScreenDemo
if (command.Trim().Equals("O", StringComparison.OrdinalIgnoreCase)) if (command.Trim().Equals("O", StringComparison.OrdinalIgnoreCase))
{ {
_ = SafeInvoke(PrimaryForm.Instance, () =>
{
PrimaryForm.Instance.HideSendOffScreen();
string marqueeMessage= "歡迎使用超級巨星歡唱網路版系統,與你共度美好時光。";
OverlayForm.MainForm.UpdateMarqueeText(marqueeMessage, OverlayForm.MarqueeStartPosition.Middle, Color.White);
});
// 開台時跳至首頁 // 開台時跳至首頁
VideoPlayerForm.publicPlaylist = new List<SongData>(); VideoPlayerForm.publicPlaylist = new List<SongData>();

View File

@ -605,7 +605,7 @@ namespace DualScreenDemo
publicPlaylist = new List<SongData>(); publicPlaylist = new List<SongData>();
// 首先添加 welcome.mpg // 首先添加 welcome.mpg
string welcomePath = @"C:\video\welcome.mpg"; string welcomePath = @"D:\video\welcome.mpg";
if (File.Exists(welcomePath)) if (File.Exists(welcomePath))
{ {
publicPlaylist.Add(new SongData( publicPlaylist.Add(new SongData(
@ -617,7 +617,7 @@ namespace DualScreenDemo
// 添加 BGM 序列 // 添加 BGM 序列
for (int i = 1; i <= 99; i++) for (int i = 1; i <= 99; i++)
{ {
string bgmPath = $@"C:\video\BGM{i:D2}.mpg"; string bgmPath = $@"D:\video\BGM{i:D2}.mpg";
if (File.Exists(bgmPath)) if (File.Exists(bgmPath))
{ {
publicPlaylist.Add(new SongData( publicPlaylist.Add(new SongData(
@ -630,7 +630,7 @@ namespace DualScreenDemo
// 如果公播清單為空,使用原有的歌曲 // 如果公播清單為空,使用原有的歌曲
if (publicPlaylist.Count == 0) if (publicPlaylist.Count == 0)
{ {
string videoDirectory = @"C:\video\"; string videoDirectory = @"D:\video\";
string[] videoFiles = Directory.GetFiles(videoDirectory, "*.mpg"); string[] videoFiles = Directory.GetFiles(videoDirectory, "*.mpg");
foreach (var songPath in videoFiles) foreach (var songPath in videoFiles)
{ {
@ -957,7 +957,7 @@ namespace DualScreenDemo
publicPlaylist = new List<SongData>(); publicPlaylist = new List<SongData>();
// 添加 welcome.mpg // 添加 welcome.mpg
string welcomePath = @"C:\video\welcome.mpg"; string welcomePath = @"D:\video\welcome.mpg";
if (File.Exists(welcomePath)) if (File.Exists(welcomePath))
{ {
publicPlaylist.Add(new SongData( publicPlaylist.Add(new SongData(
@ -968,7 +968,7 @@ namespace DualScreenDemo
// 添加 BGM 序列 // 添加 BGM 序列
for (int i = 1; i <= 99; i++) for (int i = 1; i <= 99; i++)
{ {
string bgmPath = $@"C:\video\BGM{i:D2}.mpg"; string bgmPath = $@"D:\video\BGM{i:D2}.mpg";
if (File.Exists(bgmPath)) if (File.Exists(bgmPath))
{ {
publicPlaylist.Add(new SongData( publicPlaylist.Add(new SongData(

View File

@ -4,7 +4,8 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<ApplicationIcon>Images/superstar.ico</ApplicationIcon> <ApplicationIcon>Images/superstar.ico</ApplicationIcon>
<RootNamespace>superstar_1.0.0</RootNamespace> <RootNamespace>superstar_1.1.0</RootNamespace>
<AssemblyName>superstar_1.1.0</AssemblyName>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,288 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Super Star</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Roboto', sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
}
.container {
text-align: center;
margin: 20px;
}
.header {
background: #FFA500;
padding: 10px 0;
color: white;
font-size: 24px;
font-weight: 500;
text-align: center;
}
.banner {
width: 100%;
max-width: 600px;
margin: 0 auto 20px;
}
.banner img {
width: 100%;
height: auto;
}
.menu-toggle {
position: absolute;
top: 10px;
left: 10px;
cursor: pointer;
}
.menu {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 250px;
background: white;
transform: translateX(-250px);
transition: transform 0.3s ease;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
}
.menu.active {
transform: translateX(0);
}
.menu ul {
list-style: none;
padding: 0;
margin: 0;
}
.menu ul li {
padding: 15px 20px;
border-bottom: 1px solid #ccc;
}
.menu ul li a {
text-decoration: none;
color: #333;
display: block;
}
.menu ul li a:hover {
background: #eee;
}
.container {
margin: 20px;
}
.button-container {
max-width: 600px;
margin: 0 auto;
}
.content {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
padding: 10px 20px;
max-width: 600px;
margin: 0 auto;
justify-content: center;
}
@media (max-width: 600px) {
.content {
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
}
@media (max-width: 400px) {
.content {
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.card {
width: auto;
max-width: 160px;
}
}
.card {
width: 100%;
max-width: 180px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, #FF4081, #FF4081);
color: white;
border-radius: 10px;
text-align: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
overflow: hidden;
cursor: pointer;
}
.card:hover {
transform: scale(1.05); /* 增加按鈕的點擊反應 */
}
.card img {
width: 100%;
height: auto;
object-fit: contain;
}
.section {
display: none;
}
.section.active {
display: block;
}
</style>
</head>
<body>
<div class="header">金麗都 自助式KTV</div>
<!-- Add Banner -->
<div class="banner">
<img src="手機點歌/LOGO_721x211px.png" alt="超級巨星 Banner">
</div>
<div class="menu-toggle">
<svg height="32px" id="Layer_1" style="enable-background:new 0 0 32 32;" version="1.1" viewBox="0 0 32 32" width="32px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M4,10h24c0.553,0,1-0.447,1-1s-0.447-1-1-1H4c-0.553,0-1,0.447-1,1S3.447,10,4,10z"/><path d="M28,15H4c-0.553,0-1,0.447-1,1s0.447,1,1,1h24c0.553,0,1-0.447,1-1S28.553,15,28,15z"/><path d="M28,22H4c-0.553,0-1,0.447-1,1s0.447,1,1,1h24c0.553,0,1-0.447,1-1S28.553,22,28,22z"/></svg>
</div>
<div class="menu">
<ul>
<li><a href="windows.html" class="menu-link">首頁</a></li>
<li><a href="new-songs.html" class="menu-link">新歌快報</a></li>
<li><a href="top-ranking.html" class="menu-link">熱門排行</a></li>
<li><a href="search-singer.html" class="menu-link">歌星查詢</a></li>
<li><a href="search-song.html" class="menu-link">歌名查詢</a></li>
<li><a href="clicked-song.html" class="menu-link">已點歌曲</a></li>
<!-- <!-- //<li><a href="my-favorite.html" class="menu-link">我的最愛</a></li> -->
<li><a href="sound-control.html" class="menu-link">聲音控制</a></li>
<li><a href="social-media.html" class="menu-link">社群媒體</a></li>
<li><a href="love-message.html" class="menu-link">真情告白</a></li>
<li><a href="mood-stickers.html" class="menu-link">心情貼圖</a></li>
<!-- <li><a href="song-order.html" class="menu-link">輸入點歌序號</a></li>
<li><a href="profile-settings.html" class="menu-link">會員資料設定</a></li>
<li><a href="register.html" class="menu-link">註冊會員</a></li> -->
</ul>
</div>
<div class="container">
<div class="button-container">
<div class="content">
<div class="card" onclick="location.href='new-songs.html'">
<img src="手機點歌/首頁_工作區域 1.png" alt="New Song">
</div>
<div class="card" onclick="location.href='top-ranking.html'">
<img src="手機點歌/首頁-02.png" alt="Top Ranking">
</div>
<div class="card" onclick="location.href='search-singer.html'">
<img src="手機點歌/首頁-03.png" alt="Search Singer">
</div>
<div class="card" onclick="location.href='search-song.html'">
<img src="手機點歌/首頁-04.png" alt="Search Song">
</div>
<div class="card" onclick="orderSongAndNavigate()">
<img src="手機點歌/首頁-05.png" alt="Clicked Song">
</div>
<!-- <div class="card" onclick="location.href='my-favorite.html'">
<img src="手機點歌/首頁-06.png" alt="My Favorite">
</div> -->
<div class="card" onclick="location.href='sound-control.html'">
<img src="手機點歌/首頁-07.png" alt="Sound Control">
</div>
<div class="card" onclick="location.href='social-media.html'">
<img src="手機點歌/首頁-08.png" alt="Social Media">
</div>
<div class="card" onclick="location.href='love-message.html'">
<img src="手機點歌/首頁-09.png" alt="Social Media">
</div>
<div class="card" onclick="location.href='mood-stickers.html'">
<img src="手機點歌/首頁-10.png" alt="Social Media">
</div>
</div>
</div>
</div>
<script>
var randomFolder = 'jgnq0yhxnfl'; // 這裡的 'abc123' 應由服務器生成並注入
// 獲取當前頁面的 URL
var currentURL = window.location.href;
// 檢查是否包含正確的隨機亂碼
if (!currentURL.includes('/' + randomFolder + '/')) {
// 如果不包含正確的亂碼,顯示錯誤或跳轉到正確的頁面
document.body.innerHTML = '<h1>403 Forbidden: Invalid Access</h1>';
// 也可以重定向到正確的頁面
// window.location.href = `http://${window.location.hostname}/${randomFolder}/index.html`;
}
// 首先處理導航 - 確保最高優先級
document.addEventListener('DOMContentLoaded', function() {
// 導航處理
const menuLinks = document.querySelectorAll('.menu-link');
menuLinks.forEach(link => {
// 移除所有現有的事件監聽器
const oldLink = link.cloneNode(true);
link.parentNode.replaceChild(oldLink, link);
// 添加新的點擊處理
oldLink.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
const href = this.getAttribute('href');
if (href) {
window.location.href = href;
}
}, true); // 使用捕獲階段
});
// 菜單切換
const menuToggle = document.querySelector('.menu-toggle');
const menu = document.querySelector('.menu');
if (menuToggle && menu) {
menuToggle.addEventListener('click', (e) => {
e.stopPropagation();
e.stopImmediatePropagation();
menu.classList.toggle('active');
}, true);
document.addEventListener('click', (e) => {
if (!menu.contains(e.target) && !menuToggle.contains(e.target)) {
menu.classList.remove('active');
}
}, true);
}
});
function orderSongAndNavigate() {
// 先發送 POST 請求到本機伺服器
fetch('/ordered-song', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: null
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Request successful:', data);
// 請求成功後導向到 clicked-song.html
location.href = 'clicked-song.html';
})
.catch(error => {
console.error('There was a problem with the request:', error);
// 可以在這裡顯示錯誤信息或進行其他錯誤處理
});
}
</script>
</body>
</html>

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;
@ -95,7 +95,7 @@
<!-- Add Banner --> <!-- Add Banner -->
<div class="banner"> <div class="banner">
<img src="手機點歌/BANNER-13.png" alt="超級巨星 Banner"> <img src="手機點歌/BANNER-13.png" alt="金麗都 Banner">
</div> </div>
<div class="menu-toggle"> <div class="menu-toggle">

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;
@ -157,7 +157,7 @@
<!-- Add Banner --> <!-- Add Banner -->
<div class="banner"> <div class="banner">
<img src="手機點歌/BANNER-14.png" alt="超級巨星 Banner"> <img src="手機點歌/BANNER-14.png" alt="金麗都 Banner">
</div> </div>
<div class="menu-toggle"> <div class="menu-toggle">

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;
@ -271,7 +271,7 @@
<!-- Add Banner --> <!-- Add Banner -->
<div class="banner"> <div class="banner">
<img src="手機點歌/BANNER-05.png" alt="超級巨星 Banner"> <img src="手機點歌/BANNER-05.png" alt="金麗都 Banner">
</div> </div>
<div class="menu-toggle"> <div class="menu-toggle">
@ -310,7 +310,7 @@
<tr> <tr>
<th>歌名</th> <th>歌名</th>
<th>歌手</th> <th>歌手</th>
<th>編號</th> <th>語別</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -327,7 +327,7 @@
<p>歌名:<span id="detail-song-name"></span></p> <p>歌名:<span id="detail-song-name"></span></p>
<p>編號:<span id="detail-song-number"></span></p> <p>編號:<span id="detail-song-number"></span></p>
<p>歌手:<span id="detail-singer"></span></p> <p>歌手:<span id="detail-singer"></span></p>
<p>語別:<span id="detail-language"></span></p>
<button id="order-song-button">包廂點歌</button> <button id="order-song-button">包廂點歌</button>
<button id="insert-song-button">插播歌曲</button> <button id="insert-song-button">插播歌曲</button>
</div> </div>
@ -388,16 +388,17 @@
const song = { const song = {
Song: row.cells[0].textContent, Song: row.cells[0].textContent,
ArtistA: row.cells[1].textContent, ArtistA: row.cells[1].textContent,
SongNumber: row.cells[2].textContent, Category: row.cells[2].textContent,
SongFilePathHost1: row.cells[3].textContent, SongNumber: row.cells[3].textContent,
SongFilePathHost2: row.cells[4].textContent SongFilePathHost1: row.cells[4].textContent,
SongFilePathHost2: row.cells[5].textContent
}; };
window.selectedSong = song; window.selectedSong = song;
document.getElementById('detail-song-name').textContent = song.Song; document.getElementById('detail-song-name').textContent = song.Song;
document.getElementById('detail-song-number').textContent = song.SongNumber; document.getElementById('detail-song-number').textContent = song.SongNumber;
document.getElementById('detail-singer').textContent = song.ArtistA; document.getElementById('detail-singer').textContent = song.ArtistA;
//document.getElementById('detail-language').textContent = song.Category; document.getElementById('detail-language').textContent = song.Category;
document.getElementById('song-details').style.display = 'block'; document.getElementById('song-details').style.display = 'block';
document.getElementById('overlay').style.display = 'block'; document.getElementById('overlay').style.display = 'block';
@ -542,6 +543,7 @@
row.innerHTML = ` row.innerHTML = `
<td>${song.Song}</td> <td>${song.Song}</td>
<td>${song.ArtistA}</td> <td>${song.ArtistA}</td>
<td>${song.Category}</td>
<td>${song.SongNumber}</td> <td>${song.SongNumber}</td>
<td style="display:none;">${song.SongFilePathHost1}</td> <td style="display:none;">${song.SongFilePathHost1}</td>
<td style="display:none;">${song.SongFilePathHost2}</td> <td style="display:none;">${song.SongFilePathHost2}</td>
@ -554,7 +556,7 @@
document.getElementById('detail-song-name').textContent = song.Song; document.getElementById('detail-song-name').textContent = song.Song;
document.getElementById('detail-song-number').textContent = song.SongNumber; document.getElementById('detail-song-number').textContent = song.SongNumber;
document.getElementById('detail-singer').textContent = song.ArtistA; document.getElementById('detail-singer').textContent = song.ArtistA;
document.getElementById('detail-language').textContent = song.Category;
document.getElementById('song-details').style.display = 'block'; document.getElementById('song-details').style.display = 'block';
document.getElementById('overlay').style.display = 'block'; document.getElementById('overlay').style.display = 'block';

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;
@ -291,7 +291,7 @@
<tr> <tr>
<th>歌名</th> <th>歌名</th>
<th>歌手</th> <th>歌手</th>
<th>編號</th> <th>語別</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -309,6 +309,7 @@
<p>歌名:<span id="detail-song-name"></span></p> <p>歌名:<span id="detail-song-name"></span></p>
<p>編號:<span id="detail-song-number"></span></p> <p>編號:<span id="detail-song-number"></span></p>
<p>歌手:<span id="detail-singer"></span></p> <p>歌手:<span id="detail-singer"></span></p>
<p>語別:<span id="detail-language"></span></p>
<button id="order-song-button">包廂點歌</button> <button id="order-song-button">包廂點歌</button>
<button id="insert-song-button">插播歌曲</button> <button id="insert-song-button">插播歌曲</button>
</div> </div>
@ -379,15 +380,15 @@
const row = document.createElement('tr'); const row = document.createElement('tr');
const songNameCell = document.createElement('td'); const songNameCell = document.createElement('td');
const singerCell = document.createElement('td'); const singerCell = document.createElement('td');
const SongNumberCell = document.createElement('td'); const languageCell = document.createElement('td');
songNameCell.textContent = song.Song; songNameCell.textContent = song.Song;
singerCell.textContent = song.ArtistA; singerCell.textContent = song.ArtistA;
SongNumberCell.textContent = song.SongNumber; languageCell.textContent = song.Category;
row.appendChild(songNameCell); row.appendChild(songNameCell);
row.appendChild(singerCell); row.appendChild(singerCell);
row.appendChild(SongNumberCell); row.appendChild(languageCell);
row.addEventListener('click', (e) => { row.addEventListener('click', (e) => {
e.preventDefault(); e.preventDefault();
@ -398,7 +399,7 @@
document.getElementById('detail-song-name').textContent = song.Song; document.getElementById('detail-song-name').textContent = song.Song;
document.getElementById('detail-song-number').textContent = song.SongNumber; document.getElementById('detail-song-number').textContent = song.SongNumber;
document.getElementById('detail-singer').textContent = song.ArtistA; document.getElementById('detail-singer').textContent = song.ArtistA;
//document.getElementById('detail-language').textContent = song.Category; document.getElementById('detail-language').textContent = song.Category;
document.getElementById('song-details').style.display = 'block'; document.getElementById('song-details').style.display = 'block';
}); });

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;

View File

@ -17,7 +17,7 @@
margin: 20px; margin: 20px;
} }
.header { .header {
background: #D32F2F; background: #FFA500;
padding: 10px 0; padding: 10px 0;
color: white; color: white;
font-size: 24px; font-size: 24px;
@ -136,7 +136,7 @@
</head> </head>
<body> <body>
<div class="header">超級巨星 自助式KTV</div> <div class="header">金麗都 自助式KTV</div>
<!-- Add Banner --> <!-- Add Banner -->
<div class="banner"> <div class="banner">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 KiB

After

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 KiB

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB