docs: create implementation plan for project fastwatcher
This commit is contained in:
@@ -0,0 +1,97 @@
|
|||||||
|
### 1. Temel Teknoloji Yığını ve Kütüphaneler
|
||||||
|
|
||||||
|
| Kategori | Kütüphane / Teknoloji | Neden Bu Tercih Edilmeli? |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| **State Management** | `flutter_riverpod` | SOLID'in Dependency Inversion (D) prensibini uygulamak ve servisleri izole etmek için en modern ve güvenli yöntem. |
|
||||||
|
| **Cihaz Keşfi (mDNS)** | `nsd` veya `bonsoir` | Zero-config ağ keşfi için endüstri standardı. TV kendini yayınlar, telefon bulur. |
|
||||||
|
| **Ağ İletişimi** | `shelf` (Local HTTP Server) | TV tarafında raw TCP socket yerine küçük bir REST API (HTTP Server) kurmak hata yönetimini ve loglamayı inanılmaz kolaylaştırır. |
|
||||||
|
| **Video Oynatıcı** | `media_kit` | *Chewie/Video_player yerine kesinlikle bunu kullanmalısın.* libmpv tabanlıdır. HLS (.m3u8), MKV ve özel codec'leri Android TV'de kusursuz oynatır. |
|
||||||
|
| **Link Yakalama** | `receive_sharing_intent` | Mobil cihazda tarayıcıdan "Paylaş" aksiyonunu dinlemek için. |
|
||||||
|
| **Lokal Depolama** | `shared_preferences` | Cihazın "TV" mi yoksa "Mobil" mi olduğunu ilk seçimden sonra hatırlamak için. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Proje Klasör Yapısı (Clean Architecture)
|
||||||
|
|
||||||
|
Kodun test edilebilir ve modüler olması için *Feature-First* (Özellik Odaklı) bir Clean Architecture yapısı kurmalıyız:
|
||||||
|
|
||||||
|
```text
|
||||||
|
lib/
|
||||||
|
├── core/ # Tüm projede ortak kullanılan yapılar
|
||||||
|
│ ├── constants/ # Port numaraları, API endpoint'leri
|
||||||
|
│ ├── error/ # Custom exception sınıfları
|
||||||
|
│ └── network/ # Temel ağ arayüzleri
|
||||||
|
├── features/
|
||||||
|
│ ├── setup/ # Cihaz rolü (TV/Telefon) seçim ekranı
|
||||||
|
│ ├── discovery/ # mDNS ile cihaz arama ve eşleşme (Mobil)
|
||||||
|
│ ├── receiver/ # TV tarafı: Local server ve oynatıcı
|
||||||
|
│ └── sender/ # Mobil taraf: Link yakalama ve gönderme
|
||||||
|
└── main.dart # Riverpod ProviderScope ve Init işlemleri
|
||||||
|
```
|
||||||
|
|
||||||
|
Her `feature` (özellik) kendi içinde şu üç katmana ayrılmalıdır (SOLID uygulamasının kalbi):
|
||||||
|
* **domain:** Sadece saf Dart kodları. Arayüzler (`abstract class`), entity'ler.
|
||||||
|
* **data:** Dış dünyayla iletişim. API çağrıları, paket implementasyonları.
|
||||||
|
* **presentation:** UI (Widget'lar) ve State (Riverpod Notifier'lar).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Kritik İş Akışları ve "Best Practice" Yöntemler
|
||||||
|
|
||||||
|
#### A. İlk Açılış ve Rol Seçimi (Setup)
|
||||||
|
Kullanıcı uygulamayı ilk açtığında karşısına iki dev buton çıkar: "Ben bir Telefonum (Gönderici)" ve "Ben bir TV'yim (Alıcı)".
|
||||||
|
* **Best Practice:** Bu seçim yapıldığı an `SharedPreferences`'a kaydedilir (`role = 'sender' | 'receiver'`). Uygulamanın bir sonraki açılışında `main.dart` bu değeri okur ve kullanıcıyı doğrudan ilgili ana ekrana yönlendirir.
|
||||||
|
|
||||||
|
#### B. Cihaz Eşleştirme (Discovery - mDNS)
|
||||||
|
Bluetooth yerine aynı ağda **mDNS (Zero-conf)** kullanmak en stabil "Best Practice" yöntemdir.
|
||||||
|
|
||||||
|
1. **TV (Receiver):** Uygulama açılır açılmaz arka planda `nsd` ile bir servis kaydeder. Örnek servis adı: `FastWatcher._http._tcp`. Ayrıca `shelf` ile 8080 portunda bir HTTP server dinlemeye başlar (`POST /play`).
|
||||||
|
2. **Mobil (Sender):** "Eşleş" butonuna basıldığında ağı tarar. Bulunan cihazların IP'sini bir listeye koyar. Kullanıcı TV'sine dokunduğunda IP adresi telefona kaydedilir.
|
||||||
|
|
||||||
|
#### C. İletişim Protokolü (HTTP üzerinden)
|
||||||
|
Raw Socket'ler veriyi bölebilir veya bağlantı kopmalarında sorun yaratabilir. TV'de mini bir HTTP sunucusu kurmak çok daha "Solid" bir çözümdür.
|
||||||
|
|
||||||
|
* **Mobil'in Gönderdiği Payload (JSON):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"url": "https://site.com/master.m3u8",
|
||||||
|
"title": "The Instigators (Opsiyonel)",
|
||||||
|
"timestamp": 1714415045
|
||||||
|
}
|
||||||
|
```
|
||||||
|
* **TV'nin Yanıtı:** `200 OK` (Başarıyla aldım, oynatmaya başlıyorum).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. SOLID Prensiplerinin Projeye Uygulanması
|
||||||
|
|
||||||
|
Bu projeyi "Solid" yapacak mimari kararlar şunlardır:
|
||||||
|
|
||||||
|
* **S (Tek Sorumluluk):** `DiscoveryService` sadece ağı tarar. UI'a karışmaz. Ekrana yazdırma işini `DiscoveryNotifier` (State) ve `DiscoveryScreen` yapar.
|
||||||
|
* **O (Açık/Kapalı):** İletişim katmanını bir `abstract class NetworkClient` olarak tanımla. Şu an Wi-Fi (HTTP) kullanıyoruz. Yarın Bluetooth eklemek istersen, mevcut kodu bozmadan yeni bir `BluetoothClient` implementasyonu ekleyebilirsin.
|
||||||
|
* **L (Liskov Yerine Geçme):** Eğer TV tarafında birden fazla oynatıcı motoru kullanma ihtimalin varsa (örn: `MediaKitPlayer` ve yedek olarak `ExoPlayer`), ikisi de bir `abstract class AppVideoPlayer` arayüzünden türemelidir.
|
||||||
|
* **I (Arayüz Ayrımı):** Sender ve Receiver çok farklı işler yapar. Her iki rol için devasa tek bir arayüz yazmak yerine, `ILinkSender` ve `ILinkReceiver` olarak küçük arayüzlere böl.
|
||||||
|
* **D (Bağımlılıkların Tersine Çevrilmesi):** UI sınıfların (Widget'lar) asla doğrudan `nsd` veya `shelf` paketini bilmemelidir. Araya yazdığın soyut Repository sınıflarını (Riverpod üzerinden) UI'a enjekte etmelisin.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Geliştirme Adımları (Faz Planı)
|
||||||
|
|
||||||
|
**Faz 1: Çekirdek ve İletişim (UI Olmadan)**
|
||||||
|
1. Proje yapısını ve Riverpod kurulumunu tamamla.
|
||||||
|
2. TV tarafı için `shelf` ile basit bir HTTP server yaz ve Postman ile test et.
|
||||||
|
3. TV tarafında `nsd` servisini başlat.
|
||||||
|
4. Mobil tarafta ağı tarayıp TV'nin IP'sini bulan kodu yaz.
|
||||||
|
|
||||||
|
**Faz 2: Gönderim ve Oynatma**
|
||||||
|
1. Mobil cihazdan HTTP POST ile TV'ye manuel bir test linki (.m3u8) gönder.
|
||||||
|
2. TV tarafında `media_kit` paketini kur ve gelen linki tam ekranda (kumanda odaklamalarına dikkat ederek) oynatan sayfayı tasarla.
|
||||||
|
|
||||||
|
**Faz 3: Entegrasyon (Link Yakalama)**
|
||||||
|
1. Mobil tarafa `receive_sharing_intent` paketini kur.
|
||||||
|
2. Android Manifest ayarlarını yapıp, tarayıcıdan uygulamana link düşmesini sağla.
|
||||||
|
3. Gelen linki ayrıştır (Parse) ve eşleşmiş olan TV'ye fırlat.
|
||||||
|
|
||||||
|
Bu mimariyle yazdığın bir kod hem çok hızlı çalışacak hem de aylar sonra dönüp baktığında nerede ne olduğunu saniyeler içinde bulabileceksin.
|
||||||
|
|
||||||
|
İlk olarak projeyi ayağa kaldırdıktan sonra, `shelf` ile TV tarafındaki o mini HTTP sunucusunun arayüzünü (Interface) tasarlayarak başlamak ister misin? Sana o kısmın Dependency Inversion'a uygun örnek kodunu yazabilirim.
|
||||||
Reference in New Issue
Block a user