исправил оповещения, теперь работают четко

This commit is contained in:
PC1\PTyTb
2025-08-16 22:42:29 +03:00
parent 2386d14b86
commit fd1c6b6bb8
17 changed files with 968 additions and 928 deletions
+87 -143
View File
@@ -17,13 +17,14 @@ type
FCriticalSection: TCriticalSection;
procedure IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
procedure ProcessFileRequest(ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo; const Folder: string);
procedure ProcessFileRequest(ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo; const Folder: string);
function GenerateHTML: string;
function GenerateJSON: string;
procedure CleanupOldMessages;
public
IdHTTPServer1: TIdHTTPServer;
constructor Create(FontList: TStrings; aPort:integer);
constructor Create(FontList: TStrings; aPort: integer);
destructor Destroy; override;
procedure addMessage(newMsg: TStyleEvent);
procedure ActiveServer(aEn: boolean);
@@ -35,9 +36,9 @@ uses ugeneral;
{ TTTW_Events }
constructor TTTW_Events.Create(FontList: TStrings; aPort:integer);
constructor TTTW_Events.Create(FontList: TStrings; aPort: integer);
var
I: Integer;
I: integer;
begin
FCriticalSection := TCriticalSection.Create;
FMessages := TList<TStyleEvent>.Create;
@@ -71,27 +72,19 @@ end;
procedure TTTW_Events.CleanupOldMessages;
var
I: Integer;
I: integer;
TimeNow: TDateTime;
begin
TimeNow := Now;
FCriticalSection.Enter;
try
for I := FMessages.Count - 1 downto 0 do
begin
if SecondsBetween(TimeNow, FMessages[I].Timestamp) >= FMessages[I].TimeMsg then
FMessages.Delete(I);
end;
finally
FCriticalSection.Leave;
end;
for I := FMessages.Count - 1 downto 0 do
if SecondsBetween(TimeNow, FMessages[I].Timestamp) >= FMessages[I].TimeMsg
then
FMessages.Delete(I);
end;
function TTTW_Events.GenerateHTML: string;
var
I: Integer;
I: integer;
s, s1: string;
begin
// Ãåíåðàöèÿ CSS äëÿ øðèôòîâ
@@ -99,126 +92,82 @@ begin
for I := 41 to fFontsList.Count - 1 do
begin
s1 := StringReplace(fFontsList[I], '.ttf', '', [rfReplaceAll]);
s := s + Format('@font-face { font-family: ''%s''; src: url(fonts/%s); }', [s1, fFontsList[I]]) + #13#10;
s := s + Format('@font-face { font-family: ''%s''; src: url(fonts/%s); }',
[s1, fFontsList[I]]) + #13#10;
end;
Result := '<!DOCTYPE html><html><head>' +
'<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">' +
'<meta http-equiv="Pragma" content="no-cache">' +
'<meta http-equiv="Expires" content="0">' +
'<title>Twitch Messages</title>' +
'<style>' + s +
'.message { ' +
' will-change: transform, opacity;' + // Îïòèìèçàöèÿ àíèìàöèè
' backface-visibility: hidden;' +
' transform: translateZ(0);' +
' margin:5px; ' +
' border-radius:5px; ' +
' transition: opacity 1s linear; ' +
' max-width: 600px; ' +
' margin-left: auto; ' +
' margin-right: auto; ' +
'}' +
'.nick { margin: 0; padding: 2px; }' +
'.text { margin: 0; padding: 5px; }' +
'#audio-warning { ' +
' display: none; ' +
' position: fixed; ' +
' top: 10px; ' +
' right: 10px; ' +
' background: #ffcccc; ' +
' padding: 10px; ' +
' border: 1px solid red; ' +
'}' +
'</style>' +
'<script>' +
'let lastPlayedTimestamp = 0;' +
'let audioEnabled = false;' +
'<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">'
+ '<meta http-equiv="Pragma" content="no-cache">' +
'<meta http-equiv="Expires" content="0">' + '<title>Twitch Messages</title>'
+ '<style>' + s + '.message { ' + ' will-change: transform, opacity;' +
// Îïòèìèçàöèÿ àíèìàöèè
' backface-visibility: hidden;' + ' transform: translateZ(0);' +
' margin:5px; ' + ' border-radius:5px; ' +
' transition: opacity 1s linear; ' + ' max-width: 600px; ' +
' margin-left: auto; ' + ' margin-right: auto; ' + '}' +
'.nick { margin: 0; padding: 2px; }' + '.text { margin: 0; padding: 5px; }'
+ '#audio-warning { ' + ' display: none; ' + ' position: fixed; ' +
' top: 10px; ' + ' right: 10px; ' + ' background: #ffcccc; ' +
' padding: 10px; ' + ' border: 1px solid red; ' + '}' + '</style>' +
'<script>' + 'let lastPlayedTimestamp = 0;' + 'let audioEnabled = false;' +
'let pendingMessages = [];' +
'function enableAudio() {' +
' audioEnabled = true;' +
'function enableAudio() {' + ' audioEnabled = true;' +
' document.getElementById("audio-overlay").style.display = "none";' +
' processPendingMessages();' +
'}' +
' processPendingMessages();' + '}' +
'function processPendingMessages() {' +
' pendingMessages.forEach(msg => {' +
' playNotificationSound(msg);' +
' });' +
' pendingMessages = [];' +
'}' +
'function processPendingMessages() {' + ' pendingMessages.forEach(msg => {'
+ ' playNotificationSound(msg);' + ' });' +
' pendingMessages = [];' + '}' +
'function playNotificationSound(msg) {' +
' if(!msg.sound) return;' +
' const audio = new Audio(msg.sound);' +
' audio.play()' +
' .catch(error => console.log("Audio error:", error));' +
'}' +
'function playNotificationSound(msg) {' + ' if(!msg.sound) return;' +
' const audio = new Audio(msg.sound);' + ' audio.play()' +
' .catch(error => console.log("Audio error:", error));' + '}' +
'function fetchMessages() {' +
' fetch("/messages")' +
' .then(response => response.json())' +
' .then(data => {' +
'function fetchMessages() {' + ' fetch("/messages")' +
' .then(response => response.json())' + ' .then(data => {' +
' const container = document.getElementById("messages");' +
' container.innerHTML = "";' +
' data.forEach(msg => {' +
' container.innerHTML = "";' + ' data.forEach(msg => {' +
// Ñîõðàíÿåì ñîîáùåíèÿ äî àêòèâàöèè çâóêà
// Ñîõðàíÿåì ñîîáùåíèÿ äî àêòèâàöèè çâóêà
' if(msg.sound && msg.timestamp > lastPlayedTimestamp) {' +
' playNotificationSound(msg);' +
' lastPlayedTimestamp = msg.timestamp;' +
' }' +
' lastPlayedTimestamp = msg.timestamp;' + ' }' +
' const div = document.createElement("div");' +
' div.className = "message";' +
' div.id = "msg-" + msg.timestamp;' +
' div.style = `' +
' div.id = "msg-" + msg.timestamp;' + ' div.style = `' +
' background-color: ${msg.color};' +
' padding: ${msg.padding}px;' +
' border: ${msg.sizeBorder}px solid ${msg.colorBorder};' +
' text-align: center;' +
' `;' +
' text-align: center;' + ' `;' +
// Âíóòðåííèé HTML
' let content = "";' +
' if(msg.url) {' +
' content += `<img src="${msg.url}" style="max-width: 100%; height: auto;">`;' +
' }' +
' content += `' +
' <p class="nick" style="' +
' color: ${msg.titlecolor};' +
// Âíóòðåííèé HTML
' let content = "";' + ' if(msg.url) {' +
' content += `<img src="${msg.url}" style="max-width: 100%; height: auto;">`;'
+ ' }' + ' content += `' + ' <p class="nick" style="'
+ ' color: ${msg.titlecolor};' +
' font-family: ''${msg.titlefamily}'';' +
' font-size: ${msg.titleSize}px;">' +
' ${msg.nickname}' +
' </p>' +
' ${msg.nickname}' + ' </p>' +
' <p class="text" style="' +
' color: ${msg.contentcolor};' +
' font-family: ''${msg.contentfamily}'';' +
' font-size: ${msg.contentSize}px;">' +
' ${msg.content}' +
' </p>' +
' `;' +
' ${msg.content}' + ' </p>' + ' `;' +
' div.innerHTML = content;' +
// Àíèìàöèÿ èñ÷åçíîâåíèÿ
' setTimeout(() => {' +
' div.style.opacity = "0";' +
// Àíèìàöèÿ èñ÷åçíîâåíèÿ
' setTimeout(() => {' + ' div.style.opacity = "0";' +
' setTimeout(() => div.remove(), 1000);' +
' }, (msg.duration - 1) * 1000);' +
' container.appendChild(div);' +
' });' +
' });' +
'}' +
' container.appendChild(div);' + ' });' + ' });' + '}' +
'setInterval(fetchMessages, 500);' +
'fetchMessages();' +
'</script>' +
'setInterval(fetchMessages, 1000);' + 'fetchMessages();' + '</script>' +
'</head>' +
'<body>' +
' <div id="messages"></div>' +
'</head>' + '<body>' + ' <div id="messages"></div>' +
'</body></html>';
end;
@@ -226,55 +175,49 @@ end;
function TTTW_Events.GenerateJSON: string;
var
JSONArray: TJSONArray;
I: Integer; S,S1:STRING;
I: Integer;
Msg: TStyleEvent;
begin
JSONArray := TJSONArray.Create;
try
FCriticalSection.Enter;
try
CleanupOldMessages;
for I := 0 to FMessages.Count - 1 do
begin
Msg := FMessages[I];
s:=StringReplace(Msg.FontTitle.Font,'.ttf','',[rfReplaceAll]);
s1:=StringReplace(Msg.FontContext.Font,'.ttf','',[rfReplaceAll]);
FCriticalSection.Enter;
try
for I := 0 to FMessages.Count - 1 do
begin
Msg := FMessages[I];
JSONArray.AddElement(TJSONObject.Create
.AddPair('nickname', Msg.Title)
.AddPair('url', Msg.Url)
.AddPair('content', Msg.Context)
.AddPair('timestamp', TJSONNumber.Create(DateTimeToUnix(Msg.Timestamp)))
.AddPair('sound', Msg.SoundURL)
.AddPair('duration', Msg.TimeMsg)
.AddPair('color', Msg.BlockColor)
.AddPair('colorBorder', Msg.BorderColor)
.AddPair('sizeBorder', TJSONNumber.Create(Msg.BorderSize))
.AddPair('fontSize', TJSONNumber.Create(Msg.FontTitle.size))
.AddPair('titlecolor', Msg.FontTitle.Color)
.AddPair('titlefamily', s)
.AddPair('titleSize', TJSONNumber.Create(Msg.FontTitle.Size))
.AddPair('contentcolor', Msg.FontContext.Color)
.AddPair('contentfamily', s1)
.AddPair('contentSize', TJSONNumber.Create(Msg.FontContext.Size))
); // Ôèêñèðîâàííûé ðàçìåð òåêñòà
JSONArray.AddElement(
TJSONObject.Create
.AddPair('nickname', Msg.Title)
.AddPair('url', Msg.Url)
.AddPair('content', Msg.Context)
.AddPair('timestamp', TJSONNumber.Create(DateTimeToUnix(Msg.Timestamp)))
.AddPair('sound', Msg.SoundURL)
.AddPair('duration', Msg.TimeMsg)
.AddPair('color', Msg.BlockColor)
.AddPair('colorBorder', Msg.BorderColor)
.AddPair('sizeBorder', TJSONNumber.Create(Msg.BorderSize))
.AddPair('fontSize', TJSONNumber.Create(Msg.FontTitle.Size))
.AddPair('titlecolor', Msg.FontTitle.Color)
.AddPair('titlefamily', TPath.GetFileNameWithoutExtension(Msg.FontTitle.Font))
.AddPair('titleSize', TJSONNumber.Create(Msg.FontTitle.Size))
.AddPair('contentcolor', Msg.FontContext.Color)
.AddPair('contentfamily', TPath.GetFileNameWithoutExtension(Msg.FontContext.Font))
.AddPair('contentSize', TJSONNumber.Create(Msg.FontContext.Size))
);
end;
finally
FCriticalSection.Leave;
end;
finally
FCriticalSection.Leave;
end;
Result := JSONArray.ToString;
Result := JSONArray.ToString;
finally
JSONArray.Free;
JSONArray.Free;
end;
end;
procedure TTTW_Events.ProcessFileRequest(ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo; const Folder: string);
procedure TTTW_Events.ProcessFileRequest(ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo; const Folder: string);
var
FileName: string;
FilePath: string;
@@ -290,6 +233,7 @@ begin
AResponseInfo.ContentStream := FS;
AResponseInfo.ContentType := GetMIMETypeFromFile(FilePath);;
AResponseInfo.ResponseNo := 200;
AResponseInfo.FreeContentStream := True;
except
FS.Free;
AResponseInfo.ResponseNo := 500;