Skip to content

Commit 3c04a2c

Browse files
mirkobrombinTheEvilSkeleton
authored andcommitted
Donation dialog (#3984)
1 parent eb47919 commit 3c04a2c

4 files changed

Lines changed: 62 additions & 2 deletions

File tree

bottles/backend/managers/data.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import contextlib
1919
import os
2020

21+
2122
from bottles.backend.globals import Paths
2223
from bottles.backend.logger import Logger
2324
from bottles.backend.models.samples import Samples
@@ -28,6 +29,7 @@
2829

2930
class UserDataKeys:
3031
CustomBottlesPath = "custom_bottles_path"
32+
FundingDismissed = "funding_dialog_dismissed"
3133

3234

3335
class DataManager:
@@ -67,6 +69,7 @@ def __create_data_file(self):
6769
yaml.dump(Samples.data, s)
6870
self.__get_data()
6971

72+
7073
def list(self):
7174
"""Returns the whole data dictionary."""
7275
return self.__data

bottles/backend/managers/journal.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,23 @@ def get_event(event_id: str):
172172
journal = JournalManager.__get_journal()
173173
return journal.get(event_id, None)
174174

175+
@staticmethod
176+
def first_event_date():
177+
"""Return the timestamp of the oldest event as datetime."""
178+
journal = JournalManager.__get_journal()
179+
first = None
180+
for event in journal.values():
181+
timestamp = event.get("timestamp")
182+
if not timestamp:
183+
continue
184+
try:
185+
ts = datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
186+
except (ValueError, TypeError):
187+
continue
188+
if first is None or ts < first:
189+
first = ts
190+
return first
191+
175192
@staticmethod
176193
def write(severity: JournalSeverity, message: str):
177194
"""Write an event to the journal."""

bottles/backend/models/samples.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
class Samples:
2-
data = {}
2+
data = {
3+
"funding_dialog_dismissed": False,
4+
}
35
environments = {
46
"gaming": {
57
"Runner": "wine",

bottles/frontend/windows/window.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
from bottles.backend.globals import Paths
2727
from bottles.backend.health import HealthChecker
2828
from bottles.backend.logger import Logger
29-
from bottles.backend.managers.data import UserDataKeys
29+
from datetime import datetime, timedelta
30+
31+
from bottles.backend.managers.data import DataManager, UserDataKeys
32+
from bottles.backend.managers.journal import JournalManager
3033
from bottles.backend.managers.manager import Manager
3134
from bottles.backend.models.config import BottleConfig
3235
from bottles.backend.models.result import Result
@@ -79,6 +82,16 @@ def __init__(self, arg_bottle, **kwargs):
7982

8083
super().__init__(**kwargs, default_width=width, default_height=height)
8184

85+
self.data_mgr = DataManager()
86+
first_event = JournalManager.first_event_date()
87+
days_old = 0
88+
if first_event:
89+
days_old = (datetime.now() - first_event).days
90+
91+
self._show_funding = (
92+
days_old >= 7 and not self.data_mgr.get(UserDataKeys.FundingDismissed)
93+
)
94+
8295
self.utils_conn = ConnectionUtils(
8396
force_offline=self.settings.get_boolean("force-offline")
8497
)
@@ -164,6 +177,7 @@ def response(dialog, response, *args):
164177
logging.info(
165178
"Bottles Started!",
166179
)
180+
GLib.idle_add(self.__maybe_show_funding_dialog)
167181

168182
@Gtk.Template.Callback()
169183
def on_close_request(self, *args):
@@ -359,6 +373,30 @@ def check_crash_log(self):
359373
if crash_log:
360374
CrashReportDialog(self, crash_log).present()
361375

376+
def __maybe_show_funding_dialog(self):
377+
if not self._show_funding:
378+
return
379+
380+
dialog = Adw.MessageDialog.new(
381+
self,
382+
_("Support Bottles"),
383+
_(
384+
"With over 3 million installations, Bottles is built by and for its community."
385+
"\nA donation today helps secure its future and keep it truly independent."
386+
),
387+
)
388+
dialog.add_response("donate", _("Donate"))
389+
dialog.add_response("dismiss", _("Don't Show Again"))
390+
dialog.set_response_appearance("donate", Adw.ResponseAppearance.SUGGESTED)
391+
dialog.connect("response", self.__funding_response)
392+
dialog.present()
393+
394+
def __funding_response(self, dialog, response):
395+
if response == "donate":
396+
self.open_url(None, "https://usebottles.com/funding/")
397+
self.data_mgr.set(UserDataKeys.FundingDismissed, True)
398+
dialog.destroy()
399+
362400
def toggle_selection_mode(self, status: bool = True):
363401
context = self.headerbar.get_style_context()
364402
if status:

0 commit comments

Comments
 (0)