feat: subscriptions have personalized notification times (#334)
This commit is contained in:
parent
f1815d7335
commit
c7146dfd08
@ -134,15 +134,21 @@
|
||||
$notify = []; $i = 0;
|
||||
$currentDate = new DateTime('now');
|
||||
while ($rowSubscription = $resultSubscriptions->fetchArray(SQLITE3_ASSOC)) {
|
||||
if ($rowSubscription['notify_days_before'] !== 0) {
|
||||
$daysToCompare = $rowSubscription['notify_days_before'];
|
||||
} else {
|
||||
$daysToCompare = $days;
|
||||
}
|
||||
$nextPaymentDate = new DateTime($rowSubscription['next_payment']);
|
||||
$difference = $currentDate->diff($nextPaymentDate)->days + 1;
|
||||
if ($difference === $days) {
|
||||
if ($difference === $daysToCompare) {
|
||||
$notify[$rowSubscription['payer_user_id']][$i]['name'] = $rowSubscription['name'];
|
||||
$notify[$rowSubscription['payer_user_id']][$i]['price'] = $rowSubscription['price'] . $currencies[$rowSubscription['currency_id']]['symbol'];
|
||||
$notify[$rowSubscription['payer_user_id']][$i]['currency'] = $currencies[$rowSubscription['currency_id']]['name'];
|
||||
$notify[$rowSubscription['payer_user_id']][$i]['category'] = $categories[$rowSubscription['category_id']]['name'];
|
||||
$notify[$rowSubscription['payer_user_id']][$i]['payer'] = $household[$rowSubscription['payer_user_id']]['name'];
|
||||
$notify[$rowSubscription['payer_user_id']][$i]['date'] = $rowSubscription['next_payment'];
|
||||
$notify[$rowSubscription['payer_user_id']][$i]['days'] = $daysToCompare;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
@ -163,11 +169,11 @@
|
||||
$defaultName = $defaultUser['username'];
|
||||
|
||||
foreach ($notify as $userId => $perUser) {
|
||||
$dayText = $days == 1 ? "tomorrow" : "in " . $days . " days";
|
||||
$message = "The following subscriptions are up for renewal " . $dayText . ":\n";
|
||||
$message = "The following subscriptions are up for renewal:\n";
|
||||
|
||||
foreach ($perUser as $subscription) {
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . "\n";
|
||||
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
|
||||
}
|
||||
|
||||
$mail = new PHPMailer(true);
|
||||
@ -214,15 +220,15 @@
|
||||
|
||||
$title = translate('wallos_notification', $i18n);
|
||||
|
||||
$dayText = $days == 1 ? "tomorrow" : "in " . $days . " days";
|
||||
if ($user['name']) {
|
||||
$message = $user['name'] . ", the following subscriptions are up for renewal " . $dayText . ":\n";
|
||||
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
|
||||
} else {
|
||||
$message = "The following subscriptions are up for renewal " . $dayText . ":\n";
|
||||
$message = "The following subscriptions are up for renewal:\n";
|
||||
}
|
||||
|
||||
foreach ($perUser as $subscription) {
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . "\n";
|
||||
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
|
||||
}
|
||||
|
||||
$postfields = [
|
||||
@ -267,15 +273,15 @@
|
||||
$result = $stmt->execute();
|
||||
$user = $result->fetchArray(SQLITE3_ASSOC);
|
||||
|
||||
$dayText = $days == 1 ? "tomorrow" : "in " . $days . " days";
|
||||
if ($user['name']) {
|
||||
$message = $user['name'] . ", the following subscriptions are up for renewal " . $dayText . ":\n";
|
||||
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
|
||||
} else {
|
||||
$message = "The following subscriptions are up for renewal " . $dayText . ":\n";
|
||||
$message = "The following subscriptions are up for renewal:\n";
|
||||
}
|
||||
|
||||
foreach ($perUser as $subscription) {
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . "\n";
|
||||
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
|
||||
}
|
||||
|
||||
$data = array(
|
||||
@ -312,15 +318,15 @@
|
||||
$result = $stmt->execute();
|
||||
$user = $result->fetchArray(SQLITE3_ASSOC);
|
||||
|
||||
$dayText = $days == 1 ? "tomorrow" : "in " . $days . " days";
|
||||
if ($user['name']) {
|
||||
$message = $user['name'] . ", the following subscriptions are up for renewal " . $dayText . ":\n";
|
||||
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
|
||||
} else {
|
||||
$message = "The following subscriptions are up for renewal " . $dayText . ":\n";
|
||||
$message = "The following subscriptions are up for renewal:\n";
|
||||
}
|
||||
|
||||
foreach ($perUser as $subscription) {
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . "\n";
|
||||
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
|
||||
}
|
||||
|
||||
$data = array(
|
||||
@ -357,15 +363,15 @@
|
||||
$result = $stmt->execute();
|
||||
$user = $result->fetchArray(SQLITE3_ASSOC);
|
||||
|
||||
$dayText = $days == 1 ? "tomorrow" : "in " . $days . " days";
|
||||
if ($user['name']) {
|
||||
$message = $user['name'] . ", the following subscriptions are up for renewal " . $dayText . ":\n";
|
||||
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
|
||||
} else {
|
||||
$message = "The following subscriptions are up for renewal " . $dayText . ":\n";
|
||||
$message = "The following subscriptions are up for renewal:\n";
|
||||
}
|
||||
|
||||
foreach ($perUser as $subscription) {
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . "\n";
|
||||
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
|
||||
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
@ -394,7 +400,7 @@
|
||||
if ($webhookNotificationsEnabled) {
|
||||
// Get webhook payload and turn it into a json object
|
||||
|
||||
$payload = str_replace("{{days_until}}", $days, $webhook['payload']);
|
||||
$payload = str_replace("{{days_until}}", $days, $webhook['payload']); // The default value for all subscriptions
|
||||
$payload_json = json_decode($payload, true);
|
||||
|
||||
$subscription_template = $payload_json["{{subscriptions}}"];
|
||||
@ -422,6 +428,7 @@
|
||||
$temp_subscription[$key] = str_replace("{{subscription_category}}", $subscription['category'], $temp_subscription[$key]);
|
||||
$temp_subscription[$key] = str_replace("{{subscription_payer}}", $subscription['payer'], $temp_subscription[$key]);
|
||||
$temp_subscription[$key] = str_replace("{{subscription_date}}", $subscription['date'], $temp_subscription[$key]);
|
||||
$temp_subscription[$key] = str_replace("{{subscription_days_until_payment}}", $subscription['days'], $temp_subscription[$key]); // The de facto value for this subscription
|
||||
}
|
||||
}
|
||||
$subscriptions[] = $temp_subscription;
|
||||
|
||||
@ -166,6 +166,7 @@
|
||||
$logoUrl = validate($_POST['logo-url']);
|
||||
$logo = "";
|
||||
$notify = isset($_POST['notifications']) ? true : false;
|
||||
$notifyDaysBefore = $_POST['notify_days_before'];
|
||||
$inactive = isset($_POST['inactive']) ? true : false;
|
||||
|
||||
if($logoUrl !== "") {
|
||||
@ -183,15 +184,20 @@
|
||||
|
||||
if (!$isEdit) {
|
||||
$sql = "INSERT INTO subscriptions (name, logo, price, currency_id, next_payment, cycle, frequency, notes,
|
||||
payment_method_id, payer_user_id, category_id, notify, inactive, url)
|
||||
payment_method_id, payer_user_id, category_id, notify, inactive, url, notify_days_before)
|
||||
VALUES (:name, :logo, :price, :currencyId, :nextPayment, :cycle, :frequency, :notes,
|
||||
:paymentMethodId, :payerUserId, :categoryId, :notify, :inactive, :url)";
|
||||
:paymentMethodId, :payerUserId, :categoryId, :notify, :inactive, :url, :notifyDaysBefore)";
|
||||
} else {
|
||||
$id = $_POST['id'];
|
||||
if ($logo != "") {
|
||||
$sql = "UPDATE subscriptions SET name = :name, logo = :logo, price = :price, currency_id = :currencyId, next_payment = :nextPayment, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, payer_user_id = :payerUserId, category_id = :categoryId, notify = :notify, inactive = :inactive, url = :url WHERE id = :id";
|
||||
$sql = "UPDATE subscriptions SET name = :name, logo = :logo, price = :price, currency_id = :currencyId,
|
||||
next_payment = :nextPayment, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId,
|
||||
payer_user_id = :payerUserId, category_id = :categoryId, notify = :notify, inactive = :inactive,
|
||||
url = :url, notify_days_before = :notifyDaysBefore WHERE id = :id";
|
||||
} else {
|
||||
$sql = "UPDATE subscriptions SET name = :name, price = :price, currency_id = :currencyId, next_payment = :nextPayment, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, payer_user_id = :payerUserId, category_id = :categoryId, notify = :notify, inactive = :inactive, url = :url WHERE id = :id";
|
||||
$sql = "UPDATE subscriptions SET name = :name, price = :price, currency_id = :currencyId, next_payment = :nextPayment,
|
||||
cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, payer_user_id = :payerUserId,
|
||||
category_id = :categoryId, notify = :notify, inactive = :inactive, url = :url,notify_days_before = :notifyDaysBefore WHERE id = :id";
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,6 +221,7 @@
|
||||
$stmt->bindParam(':notify', $notify, SQLITE3_INTEGER);
|
||||
$stmt->bindParam(':inactive', $inactive, SQLITE3_INTEGER);
|
||||
$stmt->bindParam(':url', $url, SQLITE3_TEXT);
|
||||
$stmt->bindParam(':notifyDaysBefore', $notifyDaysBefore, SQLITE3_INTEGER);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$success['status'] = "Success";
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
$subscriptionData['notify'] = $row['notify'];
|
||||
$subscriptionData['inactive'] = $row['inactive'];
|
||||
$subscriptionData['url'] = htmlspecialchars_decode($row['url']);
|
||||
$subscriptionData['notify_days_before'] = $row['notify_days_before'];
|
||||
|
||||
$subscriptionJson = json_encode($subscriptionData);
|
||||
header('Content-Type: application/json');
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Notizen",
|
||||
"enable_notifications" => "Benachrichtigungen für dieses Abonnement aktivieren",
|
||||
"default_value_from_settings" => "Standardwert aus den Einstellungen",
|
||||
"delete" => "Löschen",
|
||||
"cancel" => "Abbrechen",
|
||||
"upload_logo" => "Logo hochladen",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Σημειώσεις",
|
||||
"enable_notifications" => "Ενεργοποίηση ειδοποιήσεων για αυτή τη συνδρομή",
|
||||
"default_value_from_settings" => "Προεπιλεγμένη τιμή από τις ρυθμίσεις",
|
||||
"delete" => "Διαγραφή",
|
||||
"cancel" => "Ακύρωση",
|
||||
"upload_logo" => "Φόρτωση λογότυπου",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Notes",
|
||||
"enable_notifications" => "Enable Notifications for this subscription",
|
||||
"default_value_from_settings" => "Default value from settings",
|
||||
"delete" => "Delete",
|
||||
"cancel" => "Cancel",
|
||||
"upload_logo" => "Upload Logo",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Notas",
|
||||
"enable_notifications" => "Habilitar notificaciones para esta suscripción",
|
||||
"default_value_from_settings" => "Valor predeterminado de la configuración",
|
||||
"delete" => "Eliminar",
|
||||
"cancel" => "Cancelar",
|
||||
"upload_logo" => "Cargar Logotipo",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Notes",
|
||||
"enable_notifications" => "Activer les notifications pour cet abonnement",
|
||||
"default_value_from_settings" => "Valeur par défaut des paramètres",
|
||||
"delete" => "Supprimer",
|
||||
"cancel" => "Annuler",
|
||||
"upload_logo" => "Télécharger le logo",
|
||||
|
||||
@ -76,6 +76,7 @@ $i18n = [
|
||||
'url' => 'URL',
|
||||
'notes' => 'Note',
|
||||
'enable_notifications' => 'Abilita notifiche per questo abbonamento',
|
||||
'default_value_from_settings' => 'Valore predefinito dalle impostazioni',
|
||||
'delete' => 'Cancella',
|
||||
'cancel' => 'Annulla',
|
||||
'upload_logo' => 'Carica logo',
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "注釈",
|
||||
"enable_notifications" => "この定期購入の通知を有効にする",
|
||||
"default_value_from_settings" => "設定からデフォルト値を使用",
|
||||
"delete" => "削除",
|
||||
"cancel" => "キャンセル",
|
||||
"upload_logo" => "ロゴのアップロード",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "메모",
|
||||
"enable_notifications" => "이 구독에 대한 알림을 활성화합니다.",
|
||||
"default_value_from_settings" => "설정에서 기본값 사용",
|
||||
"delete" => "삭제",
|
||||
"cancel" => "취소",
|
||||
"upload_logo" => "로고 업로드",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Notatki",
|
||||
"enable_notifications" => "Włącz powiadomienia dla tej subskrypcji",
|
||||
"default_value_from_settings" => "Wartość domyślna z ustawień",
|
||||
"delete" => "Usuń",
|
||||
"cancel" => "Anuluj",
|
||||
"upload_logo" => "Prześlij logo",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Notas",
|
||||
"enable_notifications" => "Activar notificações para esta subscrição",
|
||||
"default_value_from_settings" => "Valor por defeito das definições",
|
||||
"delete" => "Remover",
|
||||
"cancel" => "Cancelar",
|
||||
"upload_logo" => "Enviar Logo",
|
||||
|
||||
@ -72,6 +72,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Anotações",
|
||||
"enable_notifications" => "Ativar notificações para essa assinatura",
|
||||
"default_value_from_settings" => "Valor padrão das configurações",
|
||||
"delete" => "Excluir",
|
||||
"cancel" => "Cancelar",
|
||||
"upload_logo" => "Enviar Logo",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Примечания",
|
||||
"enable_notifications" => "Включить уведомления для этой подписки",
|
||||
"default_value_from_settings" => "Значение по умолчанию из настроек",
|
||||
"delete" => "Удалить",
|
||||
"cancel" => "Отмена",
|
||||
"upload_logo" => "Загрузить логотип",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Beleške",
|
||||
"enable_notifications" => "Omogući obaveštenja za ovu pretplatu",
|
||||
"default_value_from_settings" => "Podrazumevana vrednost iz podešavanja",
|
||||
"delete" => "Izbriši",
|
||||
"cancel" => "Otkaži",
|
||||
"upload_logo" => "Učitaj logo",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "URL",
|
||||
"notes" => "Notlar",
|
||||
"enable_notifications" => "Bu abonelik için bildirimleri etkinleştir",
|
||||
"default_value_from_settings" => "Ayarlar'dan varsayılan değeri al",
|
||||
"delete" => "Sil",
|
||||
"cancel" => "İptal",
|
||||
"upload_logo" => "Logo Yükle",
|
||||
|
||||
@ -78,6 +78,7 @@ $i18n = [
|
||||
"url" => "链接",
|
||||
"notes" => "备注",
|
||||
"enable_notifications" => "为此订阅启用通知",
|
||||
"default_value_from_settings" => "默认值从设置中获取",
|
||||
"delete" => "删除",
|
||||
"cancel" => "取消",
|
||||
"upload_logo" => "上传 Logo",
|
||||
|
||||
@ -74,6 +74,7 @@ $i18n = [
|
||||
"url" => "連結",
|
||||
"notes" => "備註",
|
||||
"enable_notifications" => "為該訂閱開啟通知",
|
||||
"default_value_from_settings" => "從設定中取得預設值",
|
||||
"delete" => "刪除",
|
||||
"cancel" => "取消",
|
||||
"upload_logo" => "上傳圖示",
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
<?php
|
||||
$version = "v1.28.0";
|
||||
$version = "v1.29.0";
|
||||
?>
|
||||
|
||||
17
index.php
17
index.php
@ -276,10 +276,25 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group-inline">
|
||||
<input type="checkbox" id="notifications" name="notifications">
|
||||
<input type="checkbox" id="notifications" name="notifications" onchange="toggleNotificationDays()">
|
||||
<label for="notifications"><?= translate('enable_notifications', $i18n) ?></label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="notify_days_before"><?= translate('notify_me', $i18n) ?></label>
|
||||
<select id="notify_days_before" name="notify_days_before" disabled>
|
||||
<option value="0"><?= translate('default_value_from_settings', $i18n) ?></option>
|
||||
<option value="1">1 <?= translate('day_before', $i18n) ?></option>
|
||||
<?php
|
||||
for ($i = 2; $i <= 90; $i++) {
|
||||
?>
|
||||
<option value="<?= $i ?>"><?= $i ?> <?= translate('days_before', $i18n) ?></option>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="payment_method"><?= translate('payment_method', $i18n) ?></label>
|
||||
<select id="payment_method" name="payment_method_id">
|
||||
|
||||
15
migrations/000019.php
Normal file
15
migrations/000019.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*
|
||||
This migration adds a column to the subscriptuons table to store individual choice for how many days before the subscription is up for payment to notify the user
|
||||
The default value of 0 means global settings will be used
|
||||
*/
|
||||
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
$columnQuery = $db->query("SELECT * FROM pragma_table_info('subscriptions') where name='notify_days_before'");
|
||||
$columnRequired = $columnQuery->fetchArray(SQLITE3_ASSOC) === false;
|
||||
|
||||
if ($columnRequired) {
|
||||
$db->exec('ALTER TABLE subscriptions ADD COLUMN notify_days_before INTEGER DEFAULT 0');
|
||||
}
|
||||
|
||||
?>
|
||||
@ -11,6 +11,12 @@ function toggleSortOptions() {
|
||||
isSortOptionsOpen = !isSortOptionsOpen;
|
||||
}
|
||||
|
||||
function toggleNotificationDays() {
|
||||
const notifyCheckbox = document.querySelector("#notifications");
|
||||
const notifyDaysBefore = document.querySelector("#notify_days_before");
|
||||
notifyDaysBefore.disabled = !notifyCheckbox.checked;
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
const id = document.querySelector("#id");
|
||||
id.value = "";
|
||||
@ -25,6 +31,8 @@ function resetForm() {
|
||||
logoSearchButton.classList.add("disabled");
|
||||
const submitButton = document.querySelector("#save-button");
|
||||
submitButton.disabled = false;
|
||||
const notifyDaysBefore = document.querySelector("#notify_days_before");
|
||||
notifyDaysBefore.disabled = true;
|
||||
const form = document.querySelector("#subs-form");
|
||||
form.reset();
|
||||
closeLogoSearch();
|
||||
@ -77,6 +85,12 @@ function fillEditFormFields(subscription) {
|
||||
notifications.checked = subscription.notify;
|
||||
}
|
||||
|
||||
const notifyDaysBefore = document.querySelector("#notify_days_before");
|
||||
notifyDaysBefore.value = subscription.notify_days_before;
|
||||
if (subscription.notify === 1) {
|
||||
notifyDaysBefore.disabled = false;
|
||||
}
|
||||
|
||||
const deleteButton = document.querySelector("#deletesub");
|
||||
deleteButton.style = 'display: block';
|
||||
deleteButton.setAttribute("onClick", `deleteSubscription(${subscription.id})`);
|
||||
|
||||
@ -327,6 +327,7 @@
|
||||
"category": "{{subscription_category}}",
|
||||
"date": "{{subscription_date}}",
|
||||
"payer": "{{subscription_payer}}"
|
||||
"dyas": "{{subscription_days_until_payment}}"
|
||||
}
|
||||
]
|
||||
|
||||
@ -555,7 +556,7 @@
|
||||
</div>
|
||||
<div class="settings-notes">
|
||||
<p>
|
||||
<i class="fa-solid fa-circle-info"></i> <?= translate('variables_available', $i18n) ?>: {{days_until}}, {{subscription_name}}, {{subscription_price}}, {{subscription_currency}}, {{subscription_category}}, {{subscription_date}}, {{subscription_payer}}</p>
|
||||
<i class="fa-solid fa-circle-info"></i> <?= translate('variables_available', $i18n) ?>: {{days_until}}, {{subscription_name}}, {{subscription_price}}, {{subscription_currency}}, {{subscription_category}}, {{subscription_date}}, {{subscription_payer}}, {{subscription_days_until_payment}}</p>
|
||||
<p>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
|
||||
@ -1375,6 +1375,7 @@ textarea.thin {
|
||||
transform: translateX(calc(100% + 30px));
|
||||
transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.35);
|
||||
box-sizing: border-box;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user