diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 42fa09f..98ce541 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -23,10 +23,10 @@ jobs:
if: ${{ matrix.os == 'ubuntu-latest' }}
run: sudo apt-get install -y fuse libfuse2
- - name: Setup JDK 21
+ - name: Setup JDK 22
uses: actions/setup-java@v4
with:
- java-version: '21'
+ java-version: '22'
distribution: 'temurin'
- name: Setup Gradle
@@ -63,10 +63,10 @@ jobs:
if: ${{ matrix.os == 'ubuntu-latest' }}
run: sudo apt-get install -y fuse libfuse2
- - name: Setup JDK 21
+ - name: Setup JDK 22
uses: actions/setup-java@v4
with:
- java-version: '21'
+ java-version: '22'
distribution: 'temurin'
- name: Setup Gradle
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index b481867..ac81ed3 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -23,10 +23,10 @@ jobs:
if: ${{ matrix.os == 'ubuntu-latest' }}
run: sudo apt-get install -y fuse libfuse2
- - name: Setup JDK 21
+ - name: Setup JDK 22
uses: actions/setup-java@v4
with:
- java-version: '21'
+ java-version: '22'
distribution: 'temurin'
- name: Setup Gradle
diff --git a/README.md b/README.md
index 740b08a..edcc23a 100644
--- a/README.md
+++ b/README.md
@@ -115,5 +115,6 @@ This library is maintained by CodeDead. You can find more about us using the fol
* [Twitter](https://twitter.com/C0DEDEAD)
* [Facebook](https://facebook.com/deadlinecodedead)
* [Reddit](https://reddit.com/r/CodeDead)
+* [ X ](https://x.com/C0DEDEAD)
Copyright © 2024 CodeDead
diff --git a/build.gradle b/build.gradle
index d5e25a6..05366b9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -10,13 +10,13 @@ plugins {
}
group 'com.codedead'
-version '1.3.1'
+version '1.4.0'
def currentOS = DefaultNativePlatform.currentOperatingSystem
java {
- targetCompatibility = JavaVersion.VERSION_21
- sourceCompatibility = JavaVersion.VERSION_21
+ targetCompatibility = JavaVersion.VERSION_22
+ sourceCompatibility = JavaVersion.VERSION_22
}
application {
@@ -25,7 +25,7 @@ application {
}
javafx {
- version = '22'
+ version = '22.0.1'
configuration = 'implementation'
modules = ['javafx.base', 'javafx.controls', 'javafx.fxml', 'javafx.media']
}
@@ -142,9 +142,9 @@ repositories {
dependencies {
implementation 'org.apache.logging.log4j:log4j-core:2.23.1'
implementation 'io.github.mkpaz:atlantafx-base:2.0.1'
- implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.0'
- testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2'
- testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.2'
+ implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.2'
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.3'
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.3'
}
tasks.named('test') {
diff --git a/gradle/gradle-daemon-jvm.properties b/gradle/gradle-daemon-jvm.properties
new file mode 100644
index 0000000..ef4314f
--- /dev/null
+++ b/gradle/gradle-daemon-jvm.properties
@@ -0,0 +1,2 @@
+#This file is generated by updateDaemonJvm
+toolchainVersion=22
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e644113..2c35211 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index b82aa23..09523c0 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index 1aa94a4..f5feea6 100755
--- a/gradlew
+++ b/gradlew
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+# SPDX-License-Identifier: Apache-2.0
+#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
diff --git a/gradlew.bat b/gradlew.bat
index 25da30d..9d21a21 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
diff --git a/src/main/java/com/codedead/opal/controller/LanguageController.java b/src/main/java/com/codedead/opal/controller/LanguageController.java
index 1bc7d94..6395064 100644
--- a/src/main/java/com/codedead/opal/controller/LanguageController.java
+++ b/src/main/java/com/codedead/opal/controller/LanguageController.java
@@ -22,11 +22,12 @@ public static int getLanguageIndexFromLocale(final String locale) {
case "de-de" -> 1;
case "es-es" -> 2;
case "fr-fr" -> 3;
- case "jp-jp" -> 4;
- case "nl-nl" -> 5;
- case "ru-ru" -> 6;
- case "tr-tr" -> 7;
- case "zh-cn" -> 8;
+ case "hi-in" -> 4;
+ case "jp-jp" -> 5;
+ case "nl-nl" -> 6;
+ case "ru-ru" -> 7;
+ case "tr-tr" -> 8;
+ case "zh-cn" -> 9;
default -> 0;
};
}
@@ -42,11 +43,12 @@ public static String getLocaleFromLanguageIndex(final int index) {
case 1 -> "de-DE";
case 2 -> "es-ES";
case 3 -> "fr-FR";
- case 4 -> "jp-JP";
- case 5 -> "nl-NL";
- case 6 -> "ru-RU";
- case 7 -> "tr-TR";
- case 8 -> "zh-CN";
+ case 4 -> "hi-in";
+ case 5 -> "jp-JP";
+ case 6 -> "nl-NL";
+ case 7 -> "ru-RU";
+ case 8 -> "tr-TR";
+ case 9 -> "zh-CN";
default -> DEFAULT_LOCALE;
};
}
diff --git a/src/main/java/com/codedead/opal/controller/MainWindowController.java b/src/main/java/com/codedead/opal/controller/MainWindowController.java
index 9c30916..314b289 100644
--- a/src/main/java/com/codedead/opal/controller/MainWindowController.java
+++ b/src/main/java/com/codedead/opal/controller/MainWindowController.java
@@ -41,16 +41,20 @@ public final class MainWindowController implements IAudioTimer, TrayIconListener
private GridPane grpControls;
@FXML
private CheckMenuItem mniTimerEnabled;
+ @FXML
+ private MenuItem mniCountDown;
+
private TrayIconController trayIconController;
private SettingsController settingsController;
private UpdateController updateController;
private ResourceBundle translationBundle;
private TimerTask timerTask;
- private boolean timerEnabled;
+ private TimerTask countDownTask;
private final String platformName;
private final HelpUtils helpUtils;
private final ObjectMapper objectMapper;
private final Timer timer;
+ private final Timer countDownTimer;
private final IAudioTimer audioTimer;
private final Logger logger;
@@ -65,6 +69,7 @@ public MainWindowController() {
helpUtils = new HelpUtils();
this.timer = new Timer();
+ this.countDownTimer = new Timer();
this.audioTimer = this;
this.objectMapper = new ObjectMapper();
}
@@ -182,7 +187,7 @@ private void checkForUpdates(final boolean showNoUpdates, final boolean showErro
} else {
logger.info("No updates available");
if (showNoUpdates) {
- FxUtils.showInformationAlert(translationBundle.getString("NoUpdateAvailable"), null);
+ FxUtils.showInformationAlert(translationBundle.getString("NoUpdateAvailable"), getClass().getResourceAsStream(SharedVariables.ICON_URL));
}
}
} catch (final InterruptedException | IOException | InvalidHttpResponseCodeException | URISyntaxException ex) {
@@ -256,7 +261,7 @@ public void run() {
*/
@FXML
private void initialize() {
- mniTimerEnabled.setOnAction(e -> {
+ mniTimerEnabled.setOnAction(_ -> {
if (mniTimerEnabled.isSelected()) {
final Properties properties = settingsController.getProperties();
final long timerDelay = Long.parseLong(properties.getProperty("timerDelay", "3600000"));
@@ -420,7 +425,7 @@ private void settingsAction() {
primaryStage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResourceAsStream(SharedVariables.ICON_URL))));
primaryStage.setScene(new Scene(root));
- primaryStage.setOnHiding(event -> ThemeController.setTheme(settingsController.getProperties().getProperty("theme", "Light").toLowerCase()));
+ primaryStage.setOnHiding(_ -> ThemeController.setTheme(settingsController.getProperties().getProperty("theme", "Light").toLowerCase()));
logger.info("Showing the SettingsWindow");
primaryStage.show();
@@ -530,8 +535,8 @@ private void updateAction() {
*/
@Override
public void fired() {
+ cancelTimer();
getAllSoundPanes(grpControls).forEach(SoundPane::pause);
- mniTimerEnabled.setSelected(false);
if (Boolean.parseBoolean(settingsController.getProperties().getProperty("timerComputerShutdown", "false"))) {
final String command = switch (platformName.toLowerCase()) {
@@ -620,13 +625,18 @@ private void onDragDropped(final DragEvent dragEvent) {
public void cancelTimer() {
logger.info("Cancelling the Timer to stop all MediaPlayer objects");
- timerEnabled = false;
-
if (timerTask != null) {
timerTask.cancel();
timer.purge();
}
+ if (countDownTask != null) {
+ countDownTask.cancel();
+ countDownTimer.purge();
+ }
+
+ Platform.runLater(() -> mniCountDown.setVisible(false));
+
if (audioTimer != null) {
audioTimer.cancelled();
}
@@ -643,25 +653,48 @@ public void scheduleTimer(final long delay) {
logger.info("Scheduling the Timer to stop all MediaPlayer objects after {} millisecond(s)", delay);
- timerEnabled = true;
-
if (timerTask != null) {
timerTask.cancel();
timer.purge();
}
+ if (countDownTask != null) {
+ countDownTask.cancel();
+ countDownTimer.purge();
+ }
+
timerTask = new TimerTask() {
@Override
public void run() {
logger.info("Timer has fired");
- if (timerEnabled) {
- audioTimer.fired();
- }
- timerEnabled = false;
+ audioTimer.fired();
+ }
+ };
+
+ countDownTask = new TimerTask() {
+ final long seconds = delay / 1000;
+ int i = 0;
+
+ @Override
+ public void run() {
+ i++;
+ long timeLeft = (seconds - (i % seconds));
+
+ // Calculate hours, minutes and seconds
+ long hours = timeLeft / 3600;
+ long minutes = (timeLeft % 3600) / 60;
+ long seconds = timeLeft % 60;
+
+ // Format the values to HH:MM:SS with leading zeros if necessary
+ final String timeLeftFormatted = String.format("%02d:%02d:%02d", hours, minutes, seconds);
+ Platform.runLater(() -> mniCountDown.setText(timeLeftFormatted));
}
};
timer.schedule(timerTask, delay);
+ countDownTimer.schedule(countDownTask, 0, 1000);
+
+ mniCountDown.setVisible(true);
}
/**
diff --git a/src/main/java/com/codedead/opal/controller/TrayIconController.java b/src/main/java/com/codedead/opal/controller/TrayIconController.java
index 46e10c9..0ae8e48 100644
--- a/src/main/java/com/codedead/opal/controller/TrayIconController.java
+++ b/src/main/java/com/codedead/opal/controller/TrayIconController.java
@@ -61,10 +61,10 @@ private void createTrayIcon() throws IOException {
if (trayIconListener != null) {
// Platform.runLater to run on the JavaFX thread
- displayItem.addActionListener(e -> Platform.runLater(trayIconListener::onShowHide));
- settingsItem.addActionListener(e -> Platform.runLater(trayIconListener::onSettings));
- aboutItem.addActionListener(e -> Platform.runLater(trayIconListener::onAbout));
- exitItem.addActionListener(e -> Platform.runLater(trayIconListener::onExit));
+ displayItem.addActionListener(_ -> Platform.runLater(trayIconListener::onShowHide));
+ settingsItem.addActionListener(_ -> Platform.runLater(trayIconListener::onSettings));
+ aboutItem.addActionListener(_ -> Platform.runLater(trayIconListener::onAbout));
+ exitItem.addActionListener(_ -> Platform.runLater(trayIconListener::onExit));
localTrayIcon.addMouseListener(new java.awt.event.MouseAdapter() {
@Override
@@ -98,8 +98,7 @@ public void showTrayIcon() throws IOException {
logger.info("Displaying tray icon");
if (trayIcon == null) {
createTrayIcon();
- if (trayIcon == null) {
- logger.warn("TrayIcon cannot be null!");
+ if (invalidTrayIcon()) {
return;
}
}
@@ -119,8 +118,8 @@ public void showTrayIcon() throws IOException {
*/
public void hideTrayIcon() {
logger.info("Hiding tray icon");
- if (trayIcon == null) {
- logger.warn("TrayIcon cannot be null!");
+
+ if (invalidTrayIcon()) {
return;
}
@@ -129,4 +128,17 @@ public void hideTrayIcon() {
trayIcon = null;
}
+
+ /**
+ * Check if the tray icon is valid
+ *
+ * @return True if the tray icon is valid, false otherwise
+ */
+ private boolean invalidTrayIcon() {
+ if (trayIcon == null) {
+ logger.warn("TrayIcon cannot be null!");
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/main/java/com/codedead/opal/utils/SharedVariables.java b/src/main/java/com/codedead/opal/utils/SharedVariables.java
index ce69411..3e6ba5e 100644
--- a/src/main/java/com/codedead/opal/utils/SharedVariables.java
+++ b/src/main/java/com/codedead/opal/utils/SharedVariables.java
@@ -3,7 +3,7 @@
public final class SharedVariables {
public static final String ICON_URL = "/images/opal.png";
- public static final String CURRENT_VERSION = "1.3.1.0";
+ public static final String CURRENT_VERSION = "1.4.0.0";
public static final boolean PORTABLE = false;
public static final String DEFAULT_LOCALE = "en-US";
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 7ee040d..f2b6ef7 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -1,4 +1,5 @@
module Opal {
+ requires java.base;
requires java.net.http;
requires javafx.controls;
requires javafx.fxml;
@@ -6,8 +7,6 @@
requires java.compiler;
requires java.naming;
requires javafx.media;
- //noinspection Java9RedundantRequiresStatement
- requires jdk.crypto.ec; // Added for SSL handshakes
requires org.apache.logging.log4j;
requires org.apache.logging.log4j.core;
requires com.fasterxml.jackson.core;
diff --git a/src/main/resources/audio/dolphin.mp3 b/src/main/resources/audio/dolphin.mp3
new file mode 100644
index 0000000..b9866bf
Binary files /dev/null and b/src/main/resources/audio/dolphin.mp3 differ
diff --git a/src/main/resources/audio/largeCrowd.mp3 b/src/main/resources/audio/largeCrowd.mp3
new file mode 100644
index 0000000..267e9e6
Binary files /dev/null and b/src/main/resources/audio/largeCrowd.mp3 differ
diff --git a/src/main/resources/audio/rollercoaster.mp3 b/src/main/resources/audio/rollercoaster.mp3
new file mode 100644
index 0000000..fbffc73
Binary files /dev/null and b/src/main/resources/audio/rollercoaster.mp3 differ
diff --git a/src/main/resources/translations/OpalApplication.properties b/src/main/resources/translations/OpalApplication.properties
index d08359c..6131de1 100644
--- a/src/main/resources/translations/OpalApplication.properties
+++ b/src/main/resources/translations/OpalApplication.properties
@@ -1,5 +1,5 @@
About=About
-AboutText=Opal was created by DeadLine\n\nAudio: ZapSplat.com\nImages: Remix Icon\nTheme: AtlantaFX\nVersion: 1.3.1\n\nCopyright © 2024 CodeDead
+AboutText=Opal was created by DeadLine\n\nAudio: ZapSplat.com\nImages: Remix Icon\nTheme: AtlantaFX\nVersion: 1.4.0\n\nCopyright © 2024 CodeDead
AboutWindowError=Unable to open the About Window!
AboutWindowTitle=Opal - About
AutoUpdate=Automatically check for updates
@@ -93,8 +93,11 @@ TimerComputerShutdown=Shutdown computer
AudioBalance=Audio balance
Advanced=Advanced
Seagulls=Seagulls
-Belltower=Bell tower
+BellTower=Bell tower
SlowMetronome=Metronome (slow)
FastMetronome=Metronome (fast)
PlayPause=Play / Pause
PlayPauseError=Unable to play / pause!
+Dolphins=Dolphins
+RollerCoaster=Roller coaster
+LargeCrowd=Large crowd
diff --git a/src/main/resources/translations/OpalApplication_de_DE.properties b/src/main/resources/translations/OpalApplication_de_DE.properties
index 8bd5355..e7c673d 100644
--- a/src/main/resources/translations/OpalApplication_de_DE.properties
+++ b/src/main/resources/translations/OpalApplication_de_DE.properties
@@ -1,5 +1,5 @@
About=Über
-AboutText=Opal wurde erstellt von: DeadLine\n\nAudio: ZapSplat.com\nBilder: Remix Icon\nDesign: AtlantaFX\nÜbersetzung: github.com/uDEV2019\nVersion: 1.3.1\n\nCopyright © 2024 CodeDead
+AboutText=Opal wurde erstellt von: DeadLine\n\nAudio: ZapSplat.com\nBilder: Remix Icon\nDesign: AtlantaFX\nÜbersetzung: github.com/uDEV2019\nVersion: 1.4.0\n\nCopyright © 2024 CodeDead
AboutWindowError=Über-Dialog konnte nicht geöffnet werden!
AboutWindowTitle=Opal - Über
AutoUpdate=Automatisch auf Aktualisierungen prüfen
@@ -93,8 +93,11 @@ TimerComputerShutdown=Computer herunterfahren
AudioBalance=Audiobalance
Advanced=Erweitert
Seagulls=Möwen
-Belltower=Glockenturm
+BellTower=Glockenturm
SlowMetronome=Langsames Metronom
FastMetronome=Schnelles Metronom
PlayPause=Abspielen / Pause
PlayPauseError=Abspielen / Pause konnte nicht ausgeführt werden!
+Dolphins=Delfine
+RollerCoaster=Achterbahn
+LargeCrowd=Große Menschenmenge
diff --git a/src/main/resources/translations/OpalApplication_en_US.properties b/src/main/resources/translations/OpalApplication_en_US.properties
deleted file mode 100644
index d08359c..0000000
--- a/src/main/resources/translations/OpalApplication_en_US.properties
+++ /dev/null
@@ -1,100 +0,0 @@
-About=About
-AboutText=Opal was created by DeadLine\n\nAudio: ZapSplat.com\nImages: Remix Icon\nTheme: AtlantaFX\nVersion: 1.3.1\n\nCopyright © 2024 CodeDead
-AboutWindowError=Unable to open the About Window!
-AboutWindowTitle=Opal - About
-AutoUpdate=Automatically check for updates
-Birds=Birds
-Chatter=Chatter
-CheckForUpdates=Check for updates
-Close=Close
-ConfirmReset=Are you sure you want to reset all settings?
-Donate=Donate
-Exit=Exit
-File=_File
-FileExecutionError=Unable to open the file!
-Fireplace=Fireplace
-General=General
-Help=Help
-HelpFileError=Unable to open the help file!
-HelpMenu=_Help
-Homepage=Homepage
-Language=Language
-License=License
-LicenseFileError=Unable to open the license file!
-LogLevel=Log level
-MainWindowTitle=Opal
-Nature=Nature
-NewUpdateAvailable=Version {v} is now available. Would you like to download this update?
-NoUpdateAvailable=No updates available!
-Office=Office
-OpenSoundPreset=Open sound preset
-OpenSoundPresetError=Unable to open the sound preset!
-Phone=Phone
-Rain=Rain
-Reset=Reset
-ResetSettingsError=Unable to reset all settings!
-RestartRequired=A restart is required in order to change the language!
-Save=Save
-SaveSettingsError=Unable to save settings!
-SaveSoundPreset=Save sound settings
-SaveSoundPresetError=Unable to save the sound settings!
-Settings=Settings
-SettingsWindowError=Unable to open the Settings Window!
-SettingsWindowTitle=Opal - Settings
-Thunder=Thunder
-Tools=_Tools
-Traffic=Traffic
-Typing=Typing
-UpdateError=Unable to check for updates!
-WebsiteError=Unable to open website!
-Wind=Wind
-River=River
-Clock=Clock
-Static=Static
-Other=Other
-Timer=Timer
-Enabled=Enabled
-Delay=Delay
-Seconds=Second(s)
-Minutes=Minute(s)
-Hours=Hour(s)
-TimerDelayTooSmall=Timer delay cannot be smaller than 1!
-Fantasy=Fantasy
-Fan=Fan
-TimerApplicationShutdown=Exit Opal
-Cave=Cave
-Frogs=Frogs
-Zen=Zen
-Coffee=Coffee
-Zoo=Zoo
-Audiences=Audiences
-NetworkingEvent=Networking event
-TribalFestival=Tribal festival
-RugbyFootball=Rugby football
-Sleepy=Sleepy
-DrumTribalFestival=Drum tribal festival
-Gong=Gong
-MediaButtons=Media buttons
-DragDrop=Drag and drop files
-Theme=Theme
-Space=Space
-Restaurant=Restaurant
-Cancel=Cancel
-Display=Display
-TrayIcon=Tray icon
-TrayIconError=Unable to create tray icon!
-Ocean=Ocean
-Train=Train
-WhiteNoise=White noise
-RadioFrequencyStatic=Radio frequency static
-PinkNoise=Pink noise
-BrownNoise=Brown noise
-TimerComputerShutdown=Shutdown computer
-AudioBalance=Audio balance
-Advanced=Advanced
-Seagulls=Seagulls
-Belltower=Bell tower
-SlowMetronome=Metronome (slow)
-FastMetronome=Metronome (fast)
-PlayPause=Play / Pause
-PlayPauseError=Unable to play / pause!
diff --git a/src/main/resources/translations/OpalApplication_es_ES.properties b/src/main/resources/translations/OpalApplication_es_ES.properties
index baa643f..ae40330 100644
--- a/src/main/resources/translations/OpalApplication_es_ES.properties
+++ b/src/main/resources/translations/OpalApplication_es_ES.properties
@@ -1,5 +1,5 @@
About=Acerca de
-AboutText=Opal fue creado por DeadLine\n\nAudio: ZapSplat.com\nImágenes: Remix Icon\nTema: AtlantaFX\nVersión: 1.3.1\n\nCopyright © 2024 CodeDead
+AboutText=Opal fue creado por DeadLine\n\nAudio: ZapSplat.com\nImágenes: Remix Icon\nTema: AtlantaFX\nVersión: 1.4.0\n\nCopyright © 2024 CodeDead
AboutWindowError=¡No se puede abrir la ventana Acerca de!
AboutWindowTitle=Opal - Acerca de
AutoUpdate=Buscar actualizaciones automáticamente
@@ -93,8 +93,11 @@ TimerComputerShutdown=Apagar la computadora
AudioBalance=Balance de audio
Advanced=Avanzado
Seagulls=Gaviotas
-Belltower=Campanario
+BellTower=Campanario
SlowMetronome=Metronomo lento
FastMetronome=Metronomo rápido
PlayPause=Reproducir / Pausa
PlayPauseError=¡No se puede reproducir / pausar el sonido!
+Dolphins=Delfines
+RollerCoaster=Montaña rusa
+LargeCrowd=Multitud grande
diff --git a/src/main/resources/translations/OpalApplication_fr_FR.properties b/src/main/resources/translations/OpalApplication_fr_FR.properties
index b843d8c..8c4d1eb 100644
--- a/src/main/resources/translations/OpalApplication_fr_FR.properties
+++ b/src/main/resources/translations/OpalApplication_fr_FR.properties
@@ -1,5 +1,5 @@
About=À propos
-AboutText=Opal a été créé par DeadLine\n\nAudio: ZapSplat.com\nImages: Remix Icon\nThème: AtlantaFX\nVersion: 1.3.1\n\nCopyright © 2024 CodeDead
+AboutText=Opal a été créé par DeadLine\n\nAudio: ZapSplat.com\nImages: Remix Icon\nThème: AtlantaFX\nVersion: 1.4.0\n\nCopyright © 2024 CodeDead
AboutWindowError=Impossible d'ouvrir la fenêtre À propos!
AboutWindowTitle=Opal - À propos
AutoUpdate=Rechercher automatiquement les mises à jour
@@ -93,8 +93,11 @@ TimerComputerShutdown=Éteindre l'ordinateur
AudioBalance=Balance audio
Advanced=Avancé
Seagulls=Mouettes
-Belltower=Clocher
+BellTower=Clocher
SlowMetronome=Métronome lent
FastMetronome=Métronome rapide
PlayPause=Lecture / Pause
PlayPauseError=Impossible de lire / mettre en pause!
+Dolphins=Dauphins
+RollerCoaster=Montagnes russes
+LargeCrowd=Grande foule
diff --git a/src/main/resources/translations/OpalApplication_hi_IN.properties b/src/main/resources/translations/OpalApplication_hi_IN.properties
new file mode 100644
index 0000000..e1b855e
--- /dev/null
+++ b/src/main/resources/translations/OpalApplication_hi_IN.properties
@@ -0,0 +1,103 @@
+About=के बारे में
+AboutText=ओपल को डेडलाइन द्वारा बनाया गया था\n\nऑडियो: ZapSplat.com\nछवियाँ: रीमिक्स आइकन\nथीम: अटलांटाFX\nसंस्करण: 1.4.0\n\nकॉपीराइट © 2024 कोडडेड
+AboutWindowError=About विंडो खोलने में असमर्थ!
+AboutWindowTitle=Opal - के बारे में
+AutoUpdate=अपडेट के लिए स्वचालित रूप से जाँच करें
+Birds=पक्षियों
+Chatter=बकवास
+CheckForUpdates=अद्यतन के लिए जाँच
+Close=बंद करना
+ConfirmReset=क्या आप वाकई सभी सेटिंग्स रीसेट करना चाहते हैं?
+Donate=दान करें
+Exit=बाहर निकलना
+File=_फ़ाइल
+FileExecutionError=फ़ाइल खोलने में असमर्थ!
+Fireplace=चिमनी
+General=सामान्य
+Help=मदद
+HelpFileError=सहायता फ़ाइल खोलने में असमर्थ!
+HelpMenu=_मदद
+Homepage=मुखपृष्ठ
+Language=भाषा
+License=लाइसेंस
+LicenseFileError=लाइसेंस फ़ाइल खोलने में असमर्थ!
+LogLevel=छांटने का स्तर
+MainWindowTitle=Opal
+Nature=प्रकृति
+NewUpdateAvailable=संस्करण {v} अब उपलब्ध है। क्या आप यह अद्यतन डाउनलोड करना चाहेंगे?
+NoUpdateAvailable=कोई अपडेट उपलब्ध नहीं!
+Office=कार्यालय
+OpenSoundPreset=ध्वनि प्रीसेट खोलें
+OpenSoundPresetError=ध्वनि प्रीसेट खोलने में असमर्थ!
+Phone=फ़ोन
+Rain=बारिश
+Reset=रीसेट
+ResetSettingsError=सभी सेटिंग्स रीसेट करने में असमर्थ!
+RestartRequired=भाषा बदलने के लिए पुनः आरंभ करना आवश्यक है!
+Save=बचाना
+SaveSettingsError=सेटिंग्स सहेजने में असमर्थ!
+SaveSoundPreset=ध्वनि सेटिंग सहेजें
+SaveSoundPresetError=ध्वनि सेटिंग सहेजने में असमर्थ!
+Settings=समायोजन
+SettingsWindowError=सेटिंग्स विंडो खोलने में असमर्थ!
+SettingsWindowTitle=Opal - समायोजन
+Thunder=गड़गड़ाहट
+Tools=_औजार
+Traffic=ट्रैफ़िक
+Typing=टाइपिंग
+UpdateError=अद्यतनों की जांच करने में असमर्थ!
+WebsiteError=वेबसाइट खोलने में असमर्थ!
+Wind=हवा
+River=नदी
+Clock=घड़ी
+Static=स्थिर
+Other=अन्य
+Timer=घड़ी
+Enabled=सक्रिय
+Delay=देरी
+Seconds=सेकंड
+Minutes=मिनट
+Hours=घंटे
+TimerDelayTooSmall=टाइमर विलंब 1 से कम नहीं हो सकता!
+Fantasy=कल्पना
+Fan=पंखा
+TimerApplicationShutdown=बाहर निकलना Opal
+Cave=गुफ़ा
+Frogs=मेंढक
+Zen=जेन
+Coffee=कॉफी
+Zoo=चिड़ियाघर
+Audiences=ऑडियंस
+NetworkingEvent=नेटवर्किंग घटना
+TribalFestival=आदिवासी त्यौहार
+RugbyFootball=रग्बी फुटबॉल
+Sleepy=नींद
+DrumTribalFestival=ढोल आदिवासी त्यौहार
+Gong=घंटा
+MediaButtons=मीडिया बटन
+DragDrop=फ़ाइलें खींचें और छोड़ें
+Theme=विषय
+Space=अंतरिक्ष
+Restaurant=रेस्टोरेंट
+Cancel=रद्द करना
+Display=प्रदर्शन
+TrayIcon=ट्रे चिह्न
+TrayIconError=ट्रे आइकन बनाने में असमर्थ!
+Ocean=महासागर
+Train=रेलगाड़ी
+WhiteNoise=श्वेत रव
+RadioFrequencyStatic=रेडियो आवृत्ति स्थैतिक
+PinkNoise=गुलाबी शोर
+BrownNoise=भूरा शोर
+TimerComputerShutdown=कंप्यूटर बंद करें
+AudioBalance=ऑडियो संतुलन
+Advanced=विकसित
+Seagulls=सीगल
+BellTower=घंटी मीनार
+SlowMetronome=मेट्रोनोम (धीमा)
+FastMetronome=मेट्रोनोम (तेज़)
+PlayPause=चालू करे रोके
+PlayPauseError=चलाने/रोकने में असमर्थ!
+Dolphins=डाल्फिन
+RollerCoaster=रोलर कोस्टर
+LargeCrowd=बड़ी भीड़
diff --git a/src/main/resources/translations/OpalApplication_jp_JP.properties b/src/main/resources/translations/OpalApplication_jp_JP.properties
index 17e552c..6a4285a 100644
--- a/src/main/resources/translations/OpalApplication_jp_JP.properties
+++ b/src/main/resources/translations/OpalApplication_jp_JP.properties
@@ -1,5 +1,5 @@
About=このアプリについて
-AboutText=Opal は DeadLine によって作成されました\n\nオーディオ: ZapSplat.com\n画像: リミックス アイコン\nテーマ: AtlantaFX\nバージョン: 1.3.1\n\nCopyright © 2024 CodeDead
+AboutText=Opal は DeadLine によって作成されました\n\nオーディオ: ZapSplat.com\n画像: リミックス アイコン\nテーマ: AtlantaFX\nバージョン: 1.4.0\n\nCopyright © 2024 CodeDead
AboutWindowError=バージョン情報ウィンドウを開けません!
AboutWindowTitle=Opal - このアプリについて
AutoUpdate=アップデートを自動的に確認する
@@ -93,8 +93,11 @@ TimerComputerShutdown=コンピューターをシャットダウン
AudioBalance=オーディオ バランス
Advanced=高度な設定
Seagulls=カモメ
-Belltower=ベルタワー
+BellTower=ベルタワー
SlowMetronome=遅いメトロノーム
FastMetronome=速いメトロノーム
PlayPause=再生/一時停止
PlayPauseError=再生/一時停止できません!
+Dolphins=イルカ
+RollerCoaster=ローラーコースター
+LargeCrowd=大観衆
diff --git a/src/main/resources/translations/OpalApplication_nl_NL.properties b/src/main/resources/translations/OpalApplication_nl_NL.properties
index 4395c57..f910d1d 100644
--- a/src/main/resources/translations/OpalApplication_nl_NL.properties
+++ b/src/main/resources/translations/OpalApplication_nl_NL.properties
@@ -1,5 +1,5 @@
About=Over
-AboutText=Opal is gemaakt door DeadLine\n\nAudio: ZapSplat.com\nAfbeeldingen: Remix Icon\nThema: AtlantaFX\nVersie: 1.3.1\n\nCopyright © 2024 CodeDead
+AboutText=Opal is gemaakt door DeadLine\n\nAudio: ZapSplat.com\nAfbeeldingen: Remix Icon\nThema: AtlantaFX\nVersie: 1.4.0\n\nCopyright © 2024 CodeDead
AboutWindowError=Kan het Over venster niet openen!
AboutWindowTitle=Opal - Over
AutoUpdate=Automatisch controleren op updates
@@ -93,8 +93,11 @@ TimerComputerShutdown=Computer afsluiten
AudioBalance=Audio balans
Advanced=Geavanceerd
Seagulls=Meeuwen
-Belltower=Klokkentoren
+BellTower=Klokkentoren
SlowMetronome=Metronoom (langzaam)
FastMetronome=Metronoom (snel)
PlayPause=Afspelen / Pauzeren
PlayPauseError=Kan niet afspelen / pauzeren!
+Dolphins=Dolfijnen
+RollerCoaster=Achtbaan
+LargeCrowd=Grote menigte
diff --git a/src/main/resources/translations/OpalApplication_ru_RU.properties b/src/main/resources/translations/OpalApplication_ru_RU.properties
index 0fe2f28..463c58b 100644
--- a/src/main/resources/translations/OpalApplication_ru_RU.properties
+++ b/src/main/resources/translations/OpalApplication_ru_RU.properties
@@ -1,5 +1,5 @@
About=О
-AboutText=Opal был создан DeadLine\n\nАудио: ZapSplat.com\nИзображения: Remix Icon\nТема: AtlantaFX\nВерсия: 1.3.1\n\nАвторские права © 2024 CodeDead
+AboutText=Opal был создан DeadLine\n\nАудио: ZapSplat.com\nИзображения: Remix Icon\nТема: AtlantaFX\nВерсия: 1.4.0\n\nАвторские права © 2024 CodeDead
AboutWindowError=Не удается открыть окно «О программе»!
AboutWindowTitle=Opal - О компании
AutoUpdate=Автоматически проверять наличие обновлений
@@ -93,8 +93,11 @@ TimerComputerShutdown=Выключение компьютера
AudioBalance=Баланс аудио
Advanced=Дополнительно
Seagulls=Чайки
-Belltower=Колокольня
+BellTower=Колокольня
SlowMetronome=Медленный метроном
FastMetronome=Быстрый метроном
PlayPause=Воспроизведение / Пауза
PlayPauseError=Невозможно воспроизвести / приостановить воспроизведение!
+Dolphins=Дельфины
+RollerCoaster=Американские горки
+LargeCrowd=Большая толпа
diff --git a/src/main/resources/translations/OpalApplication_tr_TR.properties b/src/main/resources/translations/OpalApplication_tr_TR.properties
index f4b617c..43f9e92 100644
--- a/src/main/resources/translations/OpalApplication_tr_TR.properties
+++ b/src/main/resources/translations/OpalApplication_tr_TR.properties
@@ -1,5 +1,5 @@
About=Hakkında
-AboutText=Opal, DeadLine tarafından oluşturuldu\n\nSes: ZapSplat.com\nGörüntüler: Remix Simgesi\nTema: AtlantaFX\nSürüm: 1.3.1\n\nTelif hakkı © 2024 CodeDead
+AboutText=Opal, DeadLine tarafından oluşturuldu\n\nSes: ZapSplat.com\nGörüntüler: Remix Simgesi\nTema: AtlantaFX\nSürüm: 1.4.0\n\nTelif hakkı © 2024 CodeDead
AboutWindowError=Hakkında Penceresi açılamıyor!
AboutWindowTitle=Opal - Hakkında
AutoUpdate=Güncellemeleri otomatik olarak kontrol et
@@ -93,8 +93,11 @@ TimerComputerShutdown=Bilgisayarı Kapat
AudioBalance=Ses dengesi
Advanced=Gelişmiş
Seagulls=Martılar
-Belltower=Çan kulesi
+BellTower=Çan kulesi
SlowMetronome=Yavaş metronom
FastMetronome=Hızlı metronom
PlayPause=Oynat / Duraklat
PlayPauseError=Oynatma / Duraklatma düğmesi oluşturulamıyor!
+Dolphins=Yunuslar
+RollerCoaster=Lunapark treni
+LargeCrowd=Kalabalık
diff --git a/src/main/resources/translations/OpalApplication_zh_CN.properties b/src/main/resources/translations/OpalApplication_zh_CN.properties
index 06a6319..ed38906 100644
--- a/src/main/resources/translations/OpalApplication_zh_CN.properties
+++ b/src/main/resources/translations/OpalApplication_zh_CN.properties
@@ -1,5 +1,5 @@
About=关于
-AboutText=Opal 由 DeadLine 创建\n\n音频:ZapSplat.com\n图像:Remix Icon\n主题:AtlantaFX\n版本:1.3.1\n\n版权所有 © 2024 CodeDead
+AboutText=Opal 由 DeadLine 创建\n\n音频:ZapSplat.com\n图像:Remix Icon\n主题:AtlantaFX\n版本:1.4.0\n\n版权所有 © 2024 CodeDead
AboutWindowError=无法打开“关于”窗口!
AboutWindowTitle=Opal - 关于
AutoUpdate=自动检查更新
@@ -93,8 +93,11 @@ TimerComputerShutdown=关闭电脑
AudioBalance=音频平衡
Advanced=先进的
Seagulls=海鸥
-Belltower=钟楼
+BellTower=钟楼
SlowMetronome=慢节拍器
FastMetronome=快节拍器
PlayPause=播放 / 暂停
PlayPauseError=无法播放 / 暂停!
+Dolphins=海豚
+RollerCoaster=过山车
+LargeCrowd=大群众
diff --git a/src/main/resources/windows/MainWindow.fxml b/src/main/resources/windows/MainWindow.fxml
index c2a1996..8de90f1 100644
--- a/src/main/resources/windows/MainWindow.fxml
+++ b/src/main/resources/windows/MainWindow.fxml
@@ -93,6 +93,7 @@
+
@@ -199,6 +200,7 @@
+
@@ -238,6 +240,9 @@
+