clapp-pm 1.0.33__py3-none-any.whl → 1.0.34__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {clapp_pm-1.0.33.data → clapp_pm-1.0.34.data}/data/version.json +1 -1
  2. {clapp_pm-1.0.33.dist-info → clapp_pm-1.0.34.dist-info}/METADATA +1 -1
  3. {clapp_pm-1.0.33.dist-info → clapp_pm-1.0.34.dist-info}/RECORD +31 -11
  4. publish_command.py +17 -9
  5. test-app/clapp-packages-repo/README.md +46 -0
  6. test-app/clapp-packages-repo/index.json +40 -0
  7. test-app/clapp-packages-repo/packages/cloud-finder/README.md +164 -0
  8. test-app/clapp-packages-repo/packages/cloud-finder/main.py +985 -0
  9. test-app/clapp-packages-repo/packages/cloud-finder/manifest.json +8 -0
  10. test-app/clapp-packages-repo/packages/cloud-finder/requirements.txt +2 -0
  11. test-app/clapp-packages-repo/packages/cloud-web-browser/README.md +160 -0
  12. test-app/clapp-packages-repo/packages/cloud-web-browser/cloud_browser.py +1031 -0
  13. test-app/clapp-packages-repo/packages/cloud-web-browser/manifest.json +13 -0
  14. test-app/clapp-packages-repo/packages/cloud-web-browser/requirements.txt +4 -0
  15. test-app/clapp-packages-repo/packages/test-app/README.md +51 -0
  16. test-app/clapp-packages-repo/packages/test-app/main.py +1 -0
  17. test-app/clapp-packages-repo/packages/test-app/manifest.json +1 -0
  18. test-app/clapp-packages-repo/packages/test-app-2/README.md +51 -0
  19. test-app/clapp-packages-repo/packages/test-app-2/main.py +55 -0
  20. test-app/clapp-packages-repo/packages/test-app-2/manifest.json +15 -0
  21. test-app/clapp-packages-repo/packages.json +40 -0
  22. test-app/main.py +1 -55
  23. test-app/manifest.json +1 -15
  24. test-app/packages/test-app/README.md +51 -0
  25. test-app/packages/test-app/main.py +1 -0
  26. test-app/packages/test-app/manifest.json +1 -0
  27. version.py +1 -1
  28. {clapp_pm-1.0.33.dist-info → clapp_pm-1.0.34.dist-info}/WHEEL +0 -0
  29. {clapp_pm-1.0.33.dist-info → clapp_pm-1.0.34.dist-info}/entry_points.txt +0 -0
  30. {clapp_pm-1.0.33.dist-info → clapp_pm-1.0.34.dist-info}/licenses/LICENSE +0 -0
  31. {clapp_pm-1.0.33.dist-info → clapp_pm-1.0.34.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1031 @@
1
+ import flet as ft
2
+ from flet_webview import WebView
3
+ import webbrowser
4
+ import threading
5
+ import time
6
+
7
+ class CloudWebBrowser:
8
+ def __init__(self):
9
+ self.current_url = "https://www.google.com"
10
+ self.history = []
11
+ self.history_index = -1
12
+ self.bookmarks = []
13
+ self.tabs = [] # Sekmeler listesi
14
+ self.current_tab_index = 0 # Aktif sekme indeksi
15
+ self.downloads = [] # İndirilenler listesi
16
+
17
+ def main(self, page: ft.Page):
18
+ self.page = page # Page nesnesini sınıf içinde sakla
19
+ self.is_dark_mode = False # Tema durumu
20
+ page.title = "Cloud Web Browser"
21
+ page.theme_mode = ft.ThemeMode.LIGHT
22
+ page.window_width = 1400
23
+ page.window_height = 900
24
+ page.window_resizable = True
25
+ page.padding = 0
26
+
27
+ # URL giriş alanı
28
+ self.url_field = ft.TextField(
29
+ value=self.current_url,
30
+ expand=True,
31
+ border_radius=20,
32
+ bgcolor="white",
33
+ color="black",
34
+ text_size=14,
35
+ on_submit=self.navigate_to_url,
36
+ prefix_icon="language",
37
+ hint_text="URL girin veya arama yapın..."
38
+ )
39
+
40
+ # Navigasyon butonları
41
+ back_btn = ft.IconButton(
42
+ icon="arrow_back",
43
+ icon_color="blue600",
44
+ on_click=self.go_back,
45
+ tooltip="Geri"
46
+ )
47
+
48
+ forward_btn = ft.IconButton(
49
+ icon="arrow_forward",
50
+ icon_color="blue600",
51
+ on_click=self.go_forward,
52
+ tooltip="İleri"
53
+ )
54
+
55
+ refresh_btn = ft.IconButton(
56
+ icon="refresh",
57
+ icon_color="blue600",
58
+ on_click=self.refresh_page,
59
+ tooltip="Yenile"
60
+ )
61
+
62
+ home_btn = ft.IconButton(
63
+ icon="home",
64
+ icon_color="blue600",
65
+ on_click=self.go_home,
66
+ tooltip="Ana Sayfa"
67
+ )
68
+
69
+ bookmark_btn = ft.IconButton(
70
+ icon="bookmark_border",
71
+ icon_color="blue600",
72
+ on_click=self.toggle_bookmark,
73
+ tooltip="Yer İmi Ekle/Çıkar"
74
+ )
75
+
76
+ # external_btn kaldırıldı - hamburger menüye taşındı
77
+
78
+ # theme_btn kaldırıldı - hamburger menüye taşındı
79
+
80
+ # Sekme listesi butonu
81
+ tabs_btn = ft.IconButton(
82
+ icon="tab",
83
+ icon_color="blue600",
84
+ on_click=self.toggle_tabs_list,
85
+ tooltip="Sekme Listesi"
86
+ )
87
+
88
+ # Sekme listesi (başlangıçta gizli) - GridView ile
89
+ self.tabs_list = ft.Container(
90
+ content=ft.GridView(
91
+ controls=[],
92
+ runs_count=3, # 3 sütun
93
+ max_extent=200, # Maksimum genişlik
94
+ spacing=5,
95
+ run_spacing=5
96
+ ),
97
+ bgcolor="white",
98
+ border=ft.border.all(1, "grey300"),
99
+ border_radius=10,
100
+ padding=ft.padding.all(10),
101
+ visible=False
102
+ )
103
+
104
+ # Hamburger menü butonu
105
+ hamburger_btn = ft.IconButton(
106
+ icon="menu",
107
+ icon_color="blue600",
108
+ on_click=self.toggle_quick_access,
109
+ tooltip="Hızlı Erişim Menüsü"
110
+ )
111
+
112
+ # Navigasyon toolbar'ı
113
+ navigation_bar = ft.Container(
114
+ content=ft.Row(
115
+ controls=[
116
+ hamburger_btn,
117
+ ft.VerticalDivider(width=1, color="grey300"),
118
+ back_btn,
119
+ forward_btn,
120
+ refresh_btn,
121
+ home_btn,
122
+ bookmark_btn,
123
+ tabs_btn,
124
+ ft.VerticalDivider(width=1, color="grey300"),
125
+ self.url_field,
126
+ ft.IconButton(
127
+ icon="search",
128
+ icon_color="blue600",
129
+ on_click=self.navigate_to_url,
130
+ tooltip="Git"
131
+ )
132
+ ],
133
+ alignment=ft.MainAxisAlignment.START,
134
+ spacing=5
135
+ ),
136
+ padding=ft.padding.all(10),
137
+ bgcolor="grey50",
138
+ border=ft.border.only(bottom=ft.border.BorderSide(1, "grey300"))
139
+ )
140
+
141
+ # Hızlı erişim menüsü (NavigationDrawer) - Genişleyen bölümlerle
142
+ self.quick_access_drawer = ft.NavigationDrawer(
143
+ controls=[
144
+ ft.Container(
145
+ content=ft.Column(
146
+ controls=[
147
+ # Hızlı Erişim (Genişleyen)
148
+ ft.ExpansionTile(
149
+ title=ft.Text("Hızlı Erişim", size=16, weight=ft.FontWeight.BOLD, color="blue600"),
150
+ leading=ft.Icon("star", color="blue600"),
151
+ controls=[
152
+ ft.ListTile(
153
+ leading=ft.Icon("search", color="blue600"),
154
+ title=ft.Text("Google"),
155
+ on_click=lambda _: self.navigate_to("https://www.google.com")
156
+ ),
157
+ ft.ListTile(
158
+ leading=ft.Icon("play_arrow", color="red600"),
159
+ title=ft.Text("YouTube"),
160
+ on_click=lambda _: self.navigate_to("https://www.youtube.com")
161
+ ),
162
+ ft.ListTile(
163
+ leading=ft.Icon("code", color="grey600"),
164
+ title=ft.Text("GitHub"),
165
+ on_click=lambda _: self.navigate_to("https://github.com")
166
+ ),
167
+ ft.ListTile(
168
+ leading=ft.Icon("article", color="black"),
169
+ title=ft.Text("Wikipedia"),
170
+ on_click=lambda _: self.navigate_to("https://www.wikipedia.org")
171
+ ),
172
+ ft.ListTile(
173
+ leading=ft.Icon("question_answer", color="orange600"),
174
+ title=ft.Text("Stack Overflow"),
175
+ on_click=lambda _: self.navigate_to("https://stackoverflow.com")
176
+ ),
177
+ ft.ListTile(
178
+ leading=ft.Icon("twitter", color="blue600"),
179
+ title=ft.Text("Twitter"),
180
+ on_click=lambda _: self.navigate_to("https://twitter.com")
181
+ )
182
+ ]
183
+ ),
184
+
185
+ ft.Divider(color="grey300"),
186
+
187
+ # Yer İmleri
188
+ ft.ListTile(
189
+ leading=ft.Icon("bookmark", color="green600"),
190
+ title=ft.Text("Yer İmleri"),
191
+ on_click=self.show_bookmarks
192
+ ),
193
+
194
+ # Geçmiş
195
+ ft.ListTile(
196
+ leading=ft.Icon("history", color="purple600"),
197
+ title=ft.Text("Geçmiş"),
198
+ on_click=self.show_history
199
+ ),
200
+
201
+ # İndirilenler
202
+ ft.ListTile(
203
+ leading=ft.Icon("download", color="orange600"),
204
+ title=ft.Text("İndirilenler"),
205
+ on_click=self.show_downloads
206
+ ),
207
+
208
+ ft.Divider(color="grey300"),
209
+
210
+ # Varsayılan Tarayıcıda Aç
211
+ ft.ListTile(
212
+ leading=ft.Icon("open_in_new", color="blue600"),
213
+ title=ft.Text("Varsayılan Tarayıcıda Aç"),
214
+ on_click=self.open_external
215
+ ),
216
+
217
+ # Tema Değiştir
218
+ ft.ListTile(
219
+ leading=ft.Icon("light_mode", color="orange600"),
220
+ title=ft.Text("Tema Değiştir"),
221
+ on_click=self.toggle_theme
222
+ ),
223
+
224
+ ft.Divider(color="grey300"),
225
+
226
+ # Ayarlar
227
+ ft.ListTile(
228
+ leading=ft.Icon("settings", color="grey600"),
229
+ title=ft.Text("Ayarlar"),
230
+ on_click=self.show_settings
231
+ )
232
+ ],
233
+ spacing=5
234
+ ),
235
+ padding=ft.padding.all(20)
236
+ )
237
+ ],
238
+ bgcolor="white",
239
+ selected_index=None,
240
+ on_change=self.on_drawer_change
241
+ )
242
+
243
+ # WebView alanı
244
+ self.webview = WebView(
245
+ url=self.current_url,
246
+ expand=True,
247
+ on_page_started=self.on_page_started,
248
+ on_page_ended=self.on_page_ended,
249
+ on_web_resource_error=self.on_web_resource_error
250
+ )
251
+
252
+ # Sekme çubuğu kaldırıldı - sadece sekme listesi kullanılacak
253
+
254
+ # Ana layout
255
+ page.add(
256
+ navigation_bar,
257
+ self.tabs_list,
258
+ self.webview
259
+ )
260
+
261
+ # Drawer'ı sayfaya ekle
262
+ page.drawer = self.quick_access_drawer
263
+
264
+ # İlk sekmeyi başlat
265
+ self.tabs.append({
266
+ 'url': 'https://www.google.com',
267
+ 'title': 'Google'
268
+ })
269
+ self.update_tabs_display()
270
+
271
+ # Test için birkaç yer imi ekle
272
+ self.bookmarks = [
273
+ {'url': 'https://www.google.com', 'title': 'Google'},
274
+ {'url': 'https://www.youtube.com', 'title': 'YouTube'},
275
+ {'url': 'https://github.com', 'title': 'GitHub'}
276
+ ]
277
+
278
+ # Test için geçmiş ekle
279
+ self.history = [
280
+ 'https://www.google.com',
281
+ 'https://www.youtube.com',
282
+ 'https://github.com',
283
+ 'https://www.wikipedia.org',
284
+ 'https://stackoverflow.com'
285
+ ]
286
+ self.history_index = len(self.history) - 1
287
+
288
+ def navigate_to_url(self, e):
289
+ """URL'ye git"""
290
+ url = self.url_field.value.strip()
291
+ if not url:
292
+ return
293
+
294
+ # URL'yi düzelt
295
+ if not url.startswith(('http://', 'https://')):
296
+ if '.' in url:
297
+ url = 'https://' + url
298
+ else:
299
+ url = f'https://www.google.com/search?q={url}'
300
+
301
+ self.navigate_to(url)
302
+
303
+ def navigate_to(self, url):
304
+ """Belirtilen URL'ye git"""
305
+ self.add_to_history(url)
306
+ self.current_url = url
307
+ self.url_field.value = url
308
+ self.webview.url = url
309
+ self.webview.update()
310
+
311
+ # Aktif sekmeyi güncelle
312
+ if self.tabs and self.current_tab_index < len(self.tabs):
313
+ self.tabs[self.current_tab_index]['url'] = url
314
+ # Başlığı güncelle (basit bir yaklaşım)
315
+ if 'google.com' in url:
316
+ self.tabs[self.current_tab_index]['title'] = 'Google'
317
+ elif 'youtube.com' in url:
318
+ self.tabs[self.current_tab_index]['title'] = 'YouTube'
319
+ elif 'github.com' in url:
320
+ self.tabs[self.current_tab_index]['title'] = 'GitHub'
321
+ elif 'wikipedia.org' in url:
322
+ self.tabs[self.current_tab_index]['title'] = 'Wikipedia'
323
+ elif 'stackoverflow.com' in url:
324
+ self.tabs[self.current_tab_index]['title'] = 'Stack Overflow'
325
+ elif 'twitter.com' in url:
326
+ self.tabs[self.current_tab_index]['title'] = 'Twitter'
327
+ else:
328
+ self.tabs[self.current_tab_index]['title'] = 'Web Sayfası'
329
+ self.update_tabs_display()
330
+
331
+ def add_to_history(self, url):
332
+ """URL'yi geçmişe ekle"""
333
+ # Mevcut indeksten sonraki geçmişi temizle
334
+ self.history = self.history[:self.history_index + 1]
335
+ self.history.append(url)
336
+ self.history_index = len(self.history) - 1
337
+
338
+ def go_back(self, e):
339
+ """Geri git"""
340
+ if self.history_index > 0:
341
+ self.history_index -= 1
342
+ url = self.history[self.history_index]
343
+ self.current_url = url
344
+ self.url_field.value = url
345
+ self.webview.url = url
346
+ self.webview.update()
347
+
348
+ def go_forward(self, e):
349
+ """İleri git"""
350
+ if self.history_index < len(self.history) - 1:
351
+ self.history_index += 1
352
+ url = self.history[self.history_index]
353
+ self.current_url = url
354
+ self.url_field.value = url
355
+ self.webview.url = url
356
+ self.webview.update()
357
+
358
+ def refresh_page(self, e):
359
+ """Sayfayı yenile"""
360
+ self.webview.url = self.current_url
361
+ self.webview.update()
362
+
363
+ def go_home(self, e):
364
+ """Ana sayfaya git"""
365
+ self.navigate_to("https://www.google.com")
366
+
367
+ def toggle_bookmark(self, e):
368
+ """Yer imi ekle/çıkar"""
369
+ if self.current_url in self.bookmarks:
370
+ self.bookmarks.remove(self.current_url)
371
+ e.control.icon = "bookmark_border"
372
+ self.show_snackbar("Yer imi kaldırıldı", "orange600")
373
+ else:
374
+ self.bookmarks.append(self.current_url)
375
+ e.control.icon = "bookmark"
376
+ self.show_snackbar("Yer imi eklendi", "green600")
377
+ e.control.update()
378
+
379
+ def open_external(self, e):
380
+ """Varsayılan tarayıcıda aç"""
381
+ try:
382
+ webbrowser.open(self.current_url)
383
+ self.show_snackbar("Varsayılan tarayıcıda açıldı", "blue600")
384
+ except Exception as e:
385
+ self.show_snackbar(f"Varsayılan tarayıcı açılamadı: {str(e)}", "red600")
386
+
387
+ def toggle_quick_access(self, e):
388
+ """Hızlı erişim menüsünü aç/kapat"""
389
+ self.page.drawer.open = True
390
+ self.page.update()
391
+
392
+ def on_drawer_change(self, e):
393
+ """Drawer değişiklik olayı"""
394
+ pass
395
+
396
+ def show_settings(self, e):
397
+ """Ayarlar menüsünü göster"""
398
+ print("Ayarlar butonuna tıklandı!") # Debug bilgisi
399
+
400
+ # Basit bir mesaj göster
401
+ self.show_snackbar("Ayarlar menüsü açılıyor...", "blue600")
402
+
403
+ # Ayarlar bottom sheet oluştur
404
+ settings_bottom_sheet = ft.BottomSheet(
405
+ content=ft.Container(
406
+ content=ft.Column(
407
+ controls=[
408
+ # Başlık
409
+ ft.Container(
410
+ content=ft.Row(
411
+ controls=[
412
+ ft.Text("Ayarlar", size=20, weight=ft.FontWeight.BOLD),
413
+ ft.IconButton(
414
+ icon="close",
415
+ on_click=self.close_settings
416
+ )
417
+ ],
418
+ alignment=ft.MainAxisAlignment.SPACE_BETWEEN
419
+ ),
420
+ padding=ft.padding.all(20)
421
+ ),
422
+
423
+ ft.Divider(color="grey300"),
424
+
425
+ # Tema ayarları
426
+ ft.Container(
427
+ content=ft.Column(
428
+ controls=[
429
+ ft.Text("Tema", size=16, weight=ft.FontWeight.BOLD, color="blue600"),
430
+ ft.Row(
431
+ controls=[
432
+ ft.ElevatedButton(
433
+ "Açık Tema",
434
+ icon="light_mode",
435
+ on_click=lambda _: self.set_theme(ft.ThemeMode.LIGHT)
436
+ ),
437
+ ft.ElevatedButton(
438
+ "Koyu Tema",
439
+ icon="dark_mode",
440
+ on_click=lambda _: self.set_theme(ft.ThemeMode.DARK)
441
+ )
442
+ ],
443
+ spacing=10
444
+ )
445
+ ],
446
+ spacing=10
447
+ ),
448
+ padding=ft.padding.all(10)
449
+ ),
450
+
451
+ ft.Divider(color="grey300"),
452
+
453
+ # Tarayıcı ayarları
454
+ ft.Container(
455
+ content=ft.Column(
456
+ controls=[
457
+ ft.Text("Tarayıcı Ayarları", size=16, weight=ft.FontWeight.BOLD, color="blue600"),
458
+ ft.ListTile(
459
+ leading=ft.Icon("home", color="blue600"),
460
+ title=ft.Text("Ana Sayfa"),
461
+ subtitle=ft.Text("https://www.google.com"),
462
+ trailing=ft.IconButton(
463
+ icon="edit",
464
+ on_click=self.edit_homepage
465
+ )
466
+ ),
467
+ ft.ListTile(
468
+ leading=ft.Icon("search", color="blue600"),
469
+ title=ft.Text("Arama Motoru"),
470
+ subtitle=ft.Text("Google"),
471
+ trailing=ft.IconButton(
472
+ icon="edit",
473
+ on_click=self.edit_search_engine
474
+ )
475
+ )
476
+ ],
477
+ spacing=5
478
+ ),
479
+ padding=ft.padding.all(10)
480
+ ),
481
+
482
+ ft.Divider(color="grey300"),
483
+
484
+ # Gelişmiş ayarlar
485
+ ft.Container(
486
+ content=ft.Column(
487
+ controls=[
488
+ ft.Text("Gelişmiş", size=16, weight=ft.FontWeight.BOLD, color="blue600"),
489
+ ft.ListTile(
490
+ leading=ft.Icon("history", color="blue600"),
491
+ title=ft.Text("Geçmişi Temizle"),
492
+ on_click=self.clear_history
493
+ ),
494
+ ft.ListTile(
495
+ leading=ft.Icon("bookmark", color="blue600"),
496
+ title=ft.Text("Yer İmlerini Yönet"),
497
+ on_click=self.manage_bookmarks
498
+ ),
499
+ ft.ListTile(
500
+ leading=ft.Icon("info", color="blue600"),
501
+ title=ft.Text("Hakkında"),
502
+ on_click=self.show_about
503
+ )
504
+ ],
505
+ spacing=5
506
+ ),
507
+ padding=ft.padding.all(10)
508
+ )
509
+ ],
510
+ spacing=10,
511
+ scroll=ft.ScrollMode.AUTO
512
+ ),
513
+ padding=ft.padding.all(20),
514
+ height=500
515
+ ),
516
+ open=True
517
+ )
518
+
519
+ # Bottom sheet'i sayfaya ekle ve aç
520
+ self.page.overlay.append(settings_bottom_sheet)
521
+ self.page.drawer.open = False
522
+ self.page.update()
523
+ print("Bottom sheet açıldı!") # Debug bilgisi
524
+
525
+ def toggle_theme(self, e):
526
+ """Tema değiştir"""
527
+ self.is_dark_mode = not self.is_dark_mode
528
+ if self.is_dark_mode:
529
+ self.page.theme_mode = ft.ThemeMode.DARK
530
+ else:
531
+ self.page.theme_mode = ft.ThemeMode.LIGHT
532
+ self.page.update()
533
+ self.page.drawer.open = False
534
+ self.page.update()
535
+
536
+ def toggle_tabs_list(self, e):
537
+ """Sekme listesini aç/kapat"""
538
+ self.tabs_list.visible = not self.tabs_list.visible
539
+ if self.tabs_list.visible:
540
+ self.update_tabs_list()
541
+ self.tabs_list.update()
542
+
543
+ def update_tabs_list(self):
544
+ """Sekme listesini güncelle - GridView ile"""
545
+ self.tabs_list.content.controls.clear()
546
+
547
+ # Yeni sekme butonu (en üstte)
548
+ new_tab_btn = ft.Container(
549
+ content=ft.Column(
550
+ controls=[
551
+ ft.Icon("add", color="blue600", size=24),
552
+ ft.Text("Yeni Sekme", color="blue600", size=12, text_align=ft.TextAlign.CENTER)
553
+ ],
554
+ horizontal_alignment=ft.CrossAxisAlignment.CENTER,
555
+ spacing=5
556
+ ),
557
+ padding=ft.padding.all(12),
558
+ bgcolor="blue50",
559
+ border_radius=8,
560
+ on_click=self.new_tab
561
+ )
562
+ self.tabs_list.content.controls.append(new_tab_btn)
563
+
564
+ # Mevcut sekmeler
565
+ for i, tab in enumerate(self.tabs):
566
+ is_active = i == self.current_tab_index
567
+
568
+ # Sekme içeriği
569
+ tab_content = [
570
+ ft.Icon("tab", color="blue600" if is_active else "grey600", size=20),
571
+ ft.Text(tab['title'], color="blue600" if is_active else "black", size=11, text_align=ft.TextAlign.CENTER)
572
+ ]
573
+
574
+ # Kapatma butonu ekle (sadece birden fazla sekme varsa)
575
+ if len(self.tabs) > 1:
576
+ tab_content.append(
577
+ ft.IconButton(
578
+ icon="close",
579
+ icon_size=14,
580
+ icon_color="red600",
581
+ on_click=lambda e, idx=i: self.close_tab_from_list(idx)
582
+ )
583
+ )
584
+
585
+ tab_item = ft.Container(
586
+ content=ft.Column(
587
+ controls=tab_content,
588
+ horizontal_alignment=ft.CrossAxisAlignment.CENTER,
589
+ spacing=3
590
+ ),
591
+ padding=ft.padding.all(10),
592
+ bgcolor="blue100" if is_active else "grey50",
593
+ border_radius=8,
594
+ border=ft.border.all(1, "blue300" if is_active else "grey300"),
595
+ on_click=lambda e, idx=i: self.switch_tab_from_list(idx)
596
+ )
597
+ self.tabs_list.content.controls.append(tab_item)
598
+
599
+ def new_tab(self, e):
600
+ """Yeni sekme aç"""
601
+ new_tab_index = len(self.tabs)
602
+ self.tabs.append({
603
+ 'url': 'https://www.google.com',
604
+ 'title': 'Yeni Sekme'
605
+ })
606
+ self.current_tab_index = new_tab_index
607
+ self.update_tabs_display()
608
+ self.navigate_to('https://www.google.com')
609
+ # Sekme listesini güncelle ve gizle
610
+ if self.tabs_list.visible:
611
+ self.update_tabs_list()
612
+ self.tabs_list.visible = False
613
+ self.tabs_list.update()
614
+
615
+ def switch_tab_from_list(self, tab_index):
616
+ """Sekme listesinden sekme değiştir"""
617
+ self.switch_tab(tab_index)
618
+ # Sekme listesini gizle
619
+ self.tabs_list.visible = False
620
+ self.tabs_list.update()
621
+
622
+ def close_tab_from_list(self, tab_index):
623
+ """Sekme listesinden sekme kapat"""
624
+ self.close_tab(tab_index)
625
+ # Sekme listesini güncelle
626
+ if self.tabs_list.visible:
627
+ self.update_tabs_list()
628
+ self.tabs_list.update()
629
+
630
+ def switch_tab(self, tab_index):
631
+ """Sekme değiştir"""
632
+ if 0 <= tab_index < len(self.tabs):
633
+ self.current_tab_index = tab_index
634
+ tab = self.tabs[tab_index]
635
+ self.current_url = tab['url']
636
+ self.url_field.value = tab['url']
637
+ self.webview.url = tab['url']
638
+ self.update_tabs_display()
639
+ self.webview.update()
640
+ self.url_field.update()
641
+
642
+ def update_tabs_display(self):
643
+ """Sekme çubuğunu güncelle - artık kullanılmıyor"""
644
+ # Sekme çubuğu kaldırıldı, bu metod artık gerekli değil
645
+ pass
646
+
647
+ def close_tab(self, tab_index):
648
+ """Sekme kapat"""
649
+ if len(self.tabs) > 1:
650
+ self.tabs.pop(tab_index)
651
+ if self.current_tab_index >= len(self.tabs):
652
+ self.current_tab_index = len(self.tabs) - 1
653
+ if self.tabs:
654
+ self.switch_tab(self.current_tab_index)
655
+ self.update_tabs_display()
656
+
657
+ def show_snackbar(self, message, color):
658
+ """Snackbar mesajı göster"""
659
+ # Basit bir mesaj gösterme (gerçek uygulamada daha gelişmiş olabilir)
660
+ print(f"Mesaj: {message}")
661
+
662
+ def on_page_started(self, e):
663
+ """Sayfa yüklenmeye başladığında"""
664
+ print(f"Sayfa yükleniyor: {e.data}")
665
+
666
+ def on_page_ended(self, e):
667
+ """Sayfa yüklendiğinde"""
668
+ print(f"Sayfa yüklendi: {e.data}")
669
+ # URL'yi güncelle
670
+ if e.data and e.data != self.current_url:
671
+ self.current_url = e.data
672
+ self.url_field.value = e.data
673
+ self.url_field.update()
674
+
675
+ def on_web_resource_error(self, e):
676
+ """Web kaynağı hatası"""
677
+ print(f"Web kaynağı hatası: {e.data}")
678
+
679
+ def set_theme(self, theme_mode):
680
+ """Tema ayarla"""
681
+ self.page.theme_mode = theme_mode
682
+ self.is_dark_mode = (theme_mode == ft.ThemeMode.DARK)
683
+ self.page.update()
684
+ self.show_snackbar(f"Tema değiştirildi: {'Koyu' if self.is_dark_mode else 'Açık'}", "green600")
685
+
686
+ def edit_homepage(self, e):
687
+ """Ana sayfa düzenle"""
688
+ self.show_snackbar("Ana sayfa düzenleme yakında eklenecek", "blue600")
689
+
690
+ def edit_search_engine(self, e):
691
+ """Arama motoru düzenle"""
692
+ self.show_snackbar("Arama motoru düzenleme yakında eklenecek", "blue600")
693
+
694
+ def clear_history(self, e):
695
+ """Geçmişi temizle"""
696
+ self.history = []
697
+ self.history_index = -1
698
+ self.show_snackbar("Geçmiş temizlendi", "green600")
699
+
700
+ def manage_bookmarks(self, e):
701
+ """Yer imlerini yönet"""
702
+ self.show_snackbar("Yer imleri yönetimi yakında eklenecek", "blue600")
703
+
704
+ def show_about(self, e):
705
+ """Hakkında bilgisi göster"""
706
+ about_dialog = ft.AlertDialog(
707
+ title=ft.Text("Cloud Web Browser", size=20, weight=ft.FontWeight.BOLD),
708
+ content=ft.Column(
709
+ controls=[
710
+ ft.Text("Modern ve hızlı web tarayıcı", size=16),
711
+ ft.Text("Python ve Flet ile geliştirilmiştir", size=14, color="grey600"),
712
+ ft.Divider(color="grey300"),
713
+ ft.Text("Özellikler:", size=14, weight=ft.FontWeight.BOLD),
714
+ ft.Text("• WebView desteği", size=12),
715
+ ft.Text("• Sekme yönetimi", size=12),
716
+ ft.Text("• Hızlı erişim", size=12),
717
+ ft.Text("• Tema desteği", size=12),
718
+ ft.Text("• Yer imleri", size=12),
719
+ ft.Divider(color="grey300"),
720
+ ft.Text("Yazan: Melih Burak", size=12, color="grey600"),
721
+ ft.Text("Sürüm: 1.0", size=12, color="grey600")
722
+ ],
723
+ spacing=10
724
+ ),
725
+ actions=[
726
+ ft.TextButton("Kapat", on_click=self.close_about)
727
+ ]
728
+ )
729
+
730
+ self.page.dialog = about_dialog
731
+ about_dialog.open = True
732
+ self.page.update()
733
+
734
+ def close_about(self, e):
735
+ """Hakkında dialog'unu kapat"""
736
+ self.page.dialog.open = False
737
+ self.page.update()
738
+
739
+ def close_settings(self, e):
740
+ """Ayarlar bottom sheet'ini kapat"""
741
+ # Overlay'den bottom sheet'i kaldır
742
+ if self.page.overlay:
743
+ self.page.overlay.pop()
744
+ self.page.update()
745
+
746
+ def show_bookmarks(self, e):
747
+ """Yer imlerini göster"""
748
+ print("Yer imleri butonuna tıklandı!") # Debug bilgisi
749
+ print(f"Yer imleri sayısı: {len(self.bookmarks)}") # Debug bilgisi
750
+
751
+ if not self.bookmarks:
752
+ self.show_snackbar("Henüz yer imi eklenmemiş", "orange600")
753
+ return
754
+
755
+ # Yer imleri bottom sheet oluştur
756
+ bookmarks_bottom_sheet = ft.BottomSheet(
757
+ content=ft.Container(
758
+ content=ft.Column(
759
+ controls=[
760
+ # Başlık
761
+ ft.Container(
762
+ content=ft.Row(
763
+ controls=[
764
+ ft.Text("Yer İmleri", size=20, weight=ft.FontWeight.BOLD),
765
+ ft.IconButton(
766
+ icon="close",
767
+ on_click=self.close_bookmarks
768
+ )
769
+ ],
770
+ alignment=ft.MainAxisAlignment.SPACE_BETWEEN
771
+ ),
772
+ padding=ft.padding.all(20)
773
+ ),
774
+
775
+ ft.Divider(color="grey300"),
776
+
777
+ # Yer imleri listesi
778
+ *[ft.ListTile(
779
+ leading=ft.Icon("bookmark", color="green600"),
780
+ title=ft.Text(bookmark['title']),
781
+ subtitle=ft.Text(bookmark['url']),
782
+ trailing=ft.IconButton(
783
+ icon="delete",
784
+ icon_color="red600",
785
+ on_click=lambda e, url=bookmark['url']: self.remove_bookmark(url)
786
+ ),
787
+ on_click=lambda e, url=bookmark['url']: self.navigate_to_bookmark(url)
788
+ ) for bookmark in self.bookmarks]
789
+ ],
790
+ spacing=10,
791
+ scroll=ft.ScrollMode.AUTO
792
+ ),
793
+ padding=ft.padding.all(20),
794
+ height=400
795
+ ),
796
+ open=True
797
+ )
798
+
799
+ # Bottom sheet'i sayfaya ekle
800
+ self.page.overlay.append(bookmarks_bottom_sheet)
801
+ self.page.drawer.open = False
802
+ self.page.update()
803
+
804
+ def close_bookmarks(self, e):
805
+ """Yer imleri bottom sheet'ini kapat"""
806
+ if self.page.overlay:
807
+ self.page.overlay.pop()
808
+ self.page.update()
809
+
810
+ def navigate_to_bookmark(self, url):
811
+ """Yer imine git"""
812
+ self.navigate_to(url)
813
+ self.close_bookmarks(None)
814
+
815
+ def remove_bookmark(self, url):
816
+ """Yer imini kaldır"""
817
+ self.bookmarks = [b for b in self.bookmarks if b['url'] != url]
818
+ self.show_snackbar("Yer imi kaldırıldı", "green600")
819
+ # Bottom sheet'i yenile
820
+ self.close_bookmarks(None)
821
+ self.show_bookmarks(None)
822
+
823
+ def show_history(self, e):
824
+ """Geçmişi göster"""
825
+ print("Geçmiş butonuna tıklandı!") # Debug bilgisi
826
+ print(f"Geçmiş sayısı: {len(self.history)}") # Debug bilgisi
827
+
828
+ if not self.history:
829
+ self.show_snackbar("Geçmiş boş", "orange600")
830
+ return
831
+
832
+ # Geçmiş bottom sheet oluştur
833
+ history_bottom_sheet = ft.BottomSheet(
834
+ content=ft.Container(
835
+ content=ft.Column(
836
+ controls=[
837
+ # Başlık
838
+ ft.Container(
839
+ content=ft.Row(
840
+ controls=[
841
+ ft.Text("Geçmiş", size=20, weight=ft.FontWeight.BOLD),
842
+ ft.IconButton(
843
+ icon="close",
844
+ on_click=self.close_history
845
+ )
846
+ ],
847
+ alignment=ft.MainAxisAlignment.SPACE_BETWEEN
848
+ ),
849
+ padding=ft.padding.all(20)
850
+ ),
851
+
852
+ ft.Divider(color="grey300"),
853
+
854
+ # Geçmiş listesi (son 20 kayıt)
855
+ *[ft.ListTile(
856
+ leading=ft.Icon("history", color="purple600"),
857
+ title=ft.Text(url[:50] + "..." if len(url) > 50 else url),
858
+ subtitle=ft.Text(f"Ziyaret: {i+1}"),
859
+ on_click=lambda e, url=url: self.navigate_to_history(url)
860
+ ) for i, url in enumerate(self.history[-20:])]
861
+ ],
862
+ spacing=10,
863
+ scroll=ft.ScrollMode.AUTO
864
+ ),
865
+ padding=ft.padding.all(20),
866
+ height=400
867
+ ),
868
+ open=True
869
+ )
870
+
871
+ # Bottom sheet'i sayfaya ekle
872
+ self.page.overlay.append(history_bottom_sheet)
873
+ self.page.drawer.open = False
874
+ self.page.update()
875
+
876
+ def close_history(self, e):
877
+ """Geçmiş bottom sheet'ini kapat"""
878
+ if self.page.overlay:
879
+ self.page.overlay.pop()
880
+ self.page.update()
881
+
882
+ def navigate_to_history(self, url):
883
+ """Geçmişten URL'ye git"""
884
+ self.navigate_to(url)
885
+ self.close_history(None)
886
+
887
+ def show_downloads(self, e):
888
+ """İndirilenleri göster"""
889
+ print("İndirilenler butonuna tıklandı!") # Debug bilgisi
890
+ print(f"İndirilenler sayısı: {len(self.downloads)}") # Debug bilgisi
891
+
892
+ # İndirilenler bottom sheet oluştur
893
+ downloads_bottom_sheet = ft.BottomSheet(
894
+ content=ft.Container(
895
+ content=ft.Column(
896
+ controls=[
897
+ # Başlık
898
+ ft.Container(
899
+ content=ft.Row(
900
+ controls=[
901
+ ft.Text("İndirilenler", size=20, weight=ft.FontWeight.BOLD),
902
+ ft.IconButton(
903
+ icon="close",
904
+ on_click=self.close_downloads
905
+ )
906
+ ],
907
+ alignment=ft.MainAxisAlignment.SPACE_BETWEEN
908
+ ),
909
+ padding=ft.padding.all(20)
910
+ ),
911
+
912
+ ft.Divider(color="grey300"),
913
+
914
+ # Test indirme butonu
915
+ ft.Container(
916
+ content=ft.ElevatedButton(
917
+ "Test İndirme Başlat",
918
+ icon="download",
919
+ on_click=self.start_test_download
920
+ ),
921
+ padding=ft.padding.all(10)
922
+ ),
923
+
924
+ ft.Divider(color="grey300"),
925
+
926
+ # İndirilenler listesi
927
+ *([ft.ListTile(
928
+ leading=ft.Icon("file_download", color="green600"),
929
+ title=ft.Text(download['filename']),
930
+ subtitle=ft.Text(f"Boyut: {download['size']} - Durum: {download['status']}"),
931
+ trailing=ft.IconButton(
932
+ icon="delete",
933
+ icon_color="red600",
934
+ on_click=lambda e, filename=download['filename']: self.remove_download(filename)
935
+ )
936
+ ) for download in self.downloads] if self.downloads else [
937
+ ft.Container(
938
+ content=ft.Column(
939
+ controls=[
940
+ ft.Icon("download", color="orange600", size=48),
941
+ ft.Text("Henüz indirme yok", size=16, color="grey600"),
942
+ ft.Text("Test indirme butonunu kullanın", size=12, color="grey600")
943
+ ],
944
+ horizontal_alignment=ft.CrossAxisAlignment.CENTER,
945
+ spacing=10
946
+ ),
947
+ padding=ft.padding.all(30)
948
+ )
949
+ ])
950
+ ],
951
+ spacing=10,
952
+ scroll=ft.ScrollMode.AUTO
953
+ ),
954
+ padding=ft.padding.all(20),
955
+ height=400
956
+ ),
957
+ open=True
958
+ )
959
+
960
+ # Bottom sheet'i sayfaya ekle
961
+ self.page.overlay.append(downloads_bottom_sheet)
962
+ self.page.drawer.open = False
963
+ self.page.update()
964
+
965
+ def close_downloads(self, e):
966
+ """İndirilenler bottom sheet'ini kapat"""
967
+ if self.page.overlay:
968
+ self.page.overlay.pop()
969
+ self.page.update()
970
+
971
+ def start_test_download(self, e):
972
+ """Test indirme başlat"""
973
+ import time
974
+ import random
975
+
976
+ # Test dosya adları
977
+ test_files = [
978
+ "test_document.pdf",
979
+ "sample_image.jpg",
980
+ "example_video.mp4",
981
+ "data_file.xlsx",
982
+ "archive.zip"
983
+ ]
984
+
985
+ # Rastgele test dosyası seç
986
+ filename = random.choice(test_files)
987
+ file_size = f"{random.randint(1, 100)}.{random.randint(0, 9)} MB"
988
+
989
+ # İndirme ekle
990
+ download = {
991
+ 'filename': filename,
992
+ 'size': file_size,
993
+ 'status': 'İndiriliyor...',
994
+ 'progress': 0
995
+ }
996
+
997
+ self.downloads.append(download)
998
+ self.show_snackbar(f"İndirme başlatıldı: {filename}", "green600")
999
+
1000
+ # İndirme simülasyonu (gerçek uygulamada threading kullanılır)
1001
+ def simulate_download():
1002
+ for i in range(101):
1003
+ download['progress'] = i
1004
+ if i == 100:
1005
+ download['status'] = 'Tamamlandı'
1006
+ else:
1007
+ download['status'] = f'İndiriliyor... {i}%'
1008
+ time.sleep(0.1)
1009
+
1010
+ # Basit simülasyon
1011
+ download['status'] = 'Tamamlandı'
1012
+ download['progress'] = 100
1013
+
1014
+ # Bottom sheet'i yenile
1015
+ self.close_downloads(None)
1016
+ self.show_downloads(None)
1017
+
1018
+ def remove_download(self, filename):
1019
+ """İndirmeyi kaldır"""
1020
+ self.downloads = [d for d in self.downloads if d['filename'] != filename]
1021
+ self.show_snackbar(f"İndirme kaldırıldı: {filename}", "green600")
1022
+ # Bottom sheet'i yenile
1023
+ self.close_downloads(None)
1024
+ self.show_downloads(None)
1025
+
1026
+ def main():
1027
+ browser = CloudWebBrowser()
1028
+ ft.app(target=browser.main)
1029
+
1030
+ if __name__ == "__main__":
1031
+ main()