dodanie docker compose, dodanie nowych funkcji i poprawa działania programu

This commit is contained in:
mateusz779 2024-11-07 21:47:12 +01:00
parent f3dadd857c
commit 58c6bbc431
7 changed files with 183 additions and 52 deletions

View File

@ -5,6 +5,7 @@ WORKDIR /app
COPY go.mod go.sum* ./ COPY go.mod go.sum* ./
RUN go mod download RUN go mod download
COPY *.go ./ COPY *.go ./
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main . RUN CGO_ENABLED=0 GOOS=linux go build -o main .
# Etap minifikacji # Etap minifikacji

20
docker-compose.yml Normal file
View File

@ -0,0 +1,20 @@
version: '3.8'
services:
app:
container_name: ${PROJECT_NAME:-fast-links}
build:
context: .
dockerfile: Dockerfile
ports:
- "${PORT:-8080}:8080"
volumes:
- app-data:/data
environment:
- PORT=8080
- DATA_FILE_PATH=/data/data.db
restart: unless-stopped
# Definiujemy wolumen Docker
volumes:
app-data:

13
main.go
View File

@ -8,24 +8,17 @@ import (
"log" "log"
"mkedziora/fast-links/kvstore" "mkedziora/fast-links/kvstore"
"net/http" "net/http"
"os"
"strconv" "strconv"
"time" "time"
) )
// var (
// dataMap map[string]DataEntry
// mu sync.Mutex
// )
// func init() {
// dataMap = make(map[string]DataEntry)
// }
var store *kvstore.KVStore var store *kvstore.KVStore
func init() { func init() {
var err error var err error
store, err = kvstore.NewKVStore("data.db") filePath := os.Getenv("DATA_FILE_PATH")
store, err = kvstore.NewKVStore(filePath)
if err != nil { if err != nil {
log.Fatalf("Failed to create KVStore: %v", err) log.Fatalf("Failed to create KVStore: %v", err)
} }

View File

@ -13,7 +13,18 @@
<h1 id="info">Click the button to start.</h1> <h1 id="info">Click the button to start.</h1>
<a href="" id="url" rel="noopener noreferrer" target="_blank"></a> <a href="" id="url" rel="noopener noreferrer" target="_blank"></a>
<button id="startBtn">Start listening</button> <button id="startBtn">Start listening</button>
<div class="checkbox-container">
<input type="checkbox" id="saveOldLink" />
<label for="saveOldLink">Save old link</label>
</div>
<div class="checkbox-container">
<input type="checkbox" id="autoListen" onclick="autoListen"/>
<label for="autoListen">Auto Listen</label>
</div>
</div> </div>
<div id="toast" class="toast">This is a toast message!</div>
<script src="/js/app.js"></script> <script src="/js/app.js"></script>
</body> </body>
</html> </html>

View File

@ -23,6 +23,52 @@ body {
color: var(--text-color); color: var(--text-color);
} }
.checkbox-container {
display: flex;
align-items: center;
gap: 0.5rem;
justify-content: center;
}
.checkbox-container input[type="checkbox"] {
width: 20px;
height: 20px;
cursor: pointer;
accent-color: var(--primary-color); /* Umożliwia zmianę koloru checkboxa */
}
.checkbox-container label {
color: var(--text-color);
font-size: 0.9rem;
cursor: pointer;
transition: color 0.3s ease;
}
.checkbox-container label:hover {
color: var(--primary-color);
}
.toast {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background-color: var(--primary-color);
color: white;
padding: 1rem 1.5rem;
border-radius: 8px;
box-shadow: 0 4px 15px var(--shadow-color);
opacity: 0;
visibility: hidden;
transition: opacity 0.5s ease, visibility 0.5s ease;
z-index: 1000; /* Umożliwia wyświetlanie toastu nad innymi elementami */
}
.toast.show {
opacity: 1;
visibility: visible;
}
.container { .container {
max-width: 600px; max-width: 600px;
width: 100%; width: 100%;

View File

@ -1,18 +1,55 @@
let lastData = ""; let lastData = "";
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get("id"); const id = urlParams.get("id");
let new_url = "";
let fetchingData; let fetchingData;
let newWindow; let newWindow;
document.getElementById("startBtn").addEventListener("click", function () { let listening = false;
document.getElementById("info").textContent = "Waiting for a new address..."; const startBtn = document.getElementById("startBtn");
newWindow = window.open("about:blank", "_blank", ""); const autoListen = document.getElementById("autoListen");
const saveOldLink = document.getElementById("saveOldLink");
const info = document.getElementById("info");
const toast = document.getElementById("toast");
autoListen.addEventListener("click", function () {
if (autoListen.checked) {
saveOldLink.checked = true;
toast.textContent = "Attention! You must allow pop-ups to use this feature!";
toast.classList.add("show");
setTimeout(() => {
toast.classList.remove("show");
}, 3000);
}
});
saveOldLink.addEventListener("click", function () {
if (autoListen.checked && !this.checked) autoListen.checked = false;
});
startBtn.addEventListener("click", function () {
info.textContent = "Waiting for a new address...";
listening = !listening;
if (listening) startBtn.textContent = "Stop listening";
else {
startBtn.textContent = "Start listening";
clearInterval(fetchingData);
return;
}
if (!saveOldLink.checked) {
lastData = "";
const a = document.getElementById("url");
a.href = "";
a.textContent = "";
}
openNewTab();
fetchingData = setInterval(checkForNewAddress, 1000); fetchingData = setInterval(checkForNewAddress, 1000);
}); });
function checkForNewAddress() { function openNewTab() {
// Dodanie parametru id do URL zapytania newWindow = window.open("about:blank", "_blank", "");
}
function checkForNewAddress() {
const apiUrl = id ? `/api/get?id=${encodeURIComponent(id)}` : "/api/get"; const apiUrl = id ? `/api/get?id=${encodeURIComponent(id)}` : "/api/get";
fetch(apiUrl, { fetch(apiUrl, {
@ -39,7 +76,7 @@ function checkForNewAddress() {
const a = document.getElementById("url"); const a = document.getElementById("url");
a.href = url; a.href = url;
a.textContent = url; a.textContent = url;
console.log(newWindow);
if (newWindow) { if (newWindow) {
console.log("ustawiono nowy adres"); console.log("ustawiono nowy adres");
newWindow.location.href = id newWindow.location.href = id
@ -47,9 +84,16 @@ function checkForNewAddress() {
: "/api/url"; : "/api/url";
} }
document.getElementById("info").textContent = info.textContent =
"The page has opened; if not, click the link below. Link waiting is disabled."; "The page has opened; if not, click the link below. Link waiting is disabled.";
clearInterval(fetchingData);
if (!autoListen.checked) {
clearInterval(fetchingData);
listening = false;
document.getElementById("startBtn").textContent = "Start listening";
} else {
openNewTab();
}
} }
}) })
.catch((error) => { .catch((error) => {

View File

@ -1,50 +1,66 @@
#!/bin/sh #!/bin/bash
# Author:Mateusz Kędziora https://mkedziora.pl
# Nazwa projektu
PROJECT_NAME="fast-links" PROJECT_NAME="fast-links"
# Domyślny port
DEFAULT_PORT=8080 DEFAULT_PORT=8080
# Funkcja wyświetlająca sposób użycia # Funkcja wyświetlająca sposób użycia
usage() { usage() {
echo "Użycie: $0 [-p port]" echo "Użycie: $0 [opcje]"
echo " -p port Port na którym ma działać aplikacja (domyślnie: $DEFAULT_PORT)" echo "Opcje:"
echo " -p, --port PORT Port na którym ma działać aplikacja (domyślnie: $DEFAULT_PORT)"
echo " -b, --build Wymuś przebudowanie obrazu"
echo " -d, --down Zatrzymaj i usuń kontenery"
exit 1 exit 1
} }
# Domyślne wartości
BUILD_FLAG=""
PORT=$DEFAULT_PORT
ACTION="up"
# Przetwarzanie argumentów # Przetwarzanie argumentów
while getopts ":p:" opt; do ARGS=$(getopt -o p:bd --long port:,build,down -n "$0" -- "$@")
case ${opt} in eval set -- "$ARGS"
p )
PORT=$OPTARG while true; do
case "$1" in
-p|--port)
PORT="$2"
shift 2
;; ;;
\? ) -b|--build)
BUILD_FLAG="--build"
shift
;;
-d|--down)
ACTION="down"
shift
;;
--)
shift
break
;;
*)
usage usage
;; ;;
esac esac
done done
# Jeśli port nie został podany, użyj domyślnego # Eksportuj zmienne środowiskowe
PORT=${PORT:-$DEFAULT_PORT} export PROJECT_NAME
export PORT
# Zatrzymaj i usuń stary kontener, jeśli istnieje # Wykonaj akcję
echo "Zatrzymywanie i usuwanie starego kontenera..." if [ "$ACTION" == "down" ]; then
docker stop $PROJECT_NAME 2>/dev/null echo "Zatrzymywanie i usuwanie kontenerów..."
docker rm $PROJECT_NAME 2>/dev/null docker compose down
else
echo "Uruchamianie kontenera na porcie $PORT..."
docker compose up -d $BUILD_FLAG
# Zbuduj nowy obraz # Wyświetl informacje o uruchomionym kontenerze
echo "Budowanie nowego obrazu..." echo "Kontener uruchomiony. Szczegóły:"
docker build -t $PROJECT_NAME . docker compose ps
# Uruchom nowy kontener echo "Aplikacja dostępna pod adresem: http://0.0.0.0:$PORT"
echo "Uruchamianie nowego kontenera na porcie $PORT..." fi
docker run -d --name $PROJECT_NAME -p $PORT:8080 $PROJECT_NAME
# Wyświetl informacje o uruchomionym kontenerze
echo "Kontener uruchomiony. Szczegóły:"
docker ps --filter name=$PROJECT_NAME
echo "Aplikacja dostępna pod adresem: http://localhost:$PORT"