# sudarev_home Small home-screen helpers for Flutter apps, by Rasnex: - **Made by footer** – a one-line `Made by · ` link at the bottom of root screens (`MadeBySignature`, `MadeByFooter`). You pass the name and the URL. - **App icon quick actions** – the long-press menu on the app icon (iOS Quick Actions, Android App Shortcuts) with a plain, testable model (`HomeAction`, `HomeActions`). - **Home-screen widgets** – push flat strings to iOS WidgetKit / Android AppWidget and route widget taps to a tab or an action (`HomeWidgets`, `HomeSnapshot`, `HomeWidgetLink`). Native templates are in [`native/`](native/). Built on [`quick_actions`](https://pub.dev/packages/quick_actions), [`home_widget`](https://pub.dev/packages/home_widget) and [`url_launcher`](https://pub.dev/packages/url_launcher). Quick actions and widgets work on iOS and Android; on web and desktop the calls are safe no-ops. ## Install ```yaml dependencies: sudarev_home: ^0.1.0 ``` ```dart import 'package:sudarev_home/sudarev_home.dart'; ``` ## Made by footer Add the line under every root screen with two lines of setup. Pushed screens, dialogs and the open keyboard hide it. ```dart MaterialApp( navigatorObservers: [MadeByFooter.observer], builder: MadeByFooter.builder( author: 'Your Studio', url: Uri.parse('https://example.com'), ), home: const HomePage(), ); ``` Already have a `builder`? Wrap your result: ```dart builder: (context, child) => MadeByFooter.wrap( context, MyWrapper(child: child!), author: 'Your Studio', url: Uri.parse('https://example.com'), ), ``` Or place the widget yourself: ```dart const MadeBySignature(author: 'Your Studio'); // plain text, no link MadeBySignature( author: 'Your Studio', url: Uri.parse('https://example.com/games/snake'), siteText: 'example.com', // label after the dot (defaults to host + path) prefix: 'Built by', // default: "Made by" / "Сделано:" for ru locale ); ``` The text follows the app locale (`ru` → `Сделано:`, otherwise `Made by`); pass `ru: true/false` to force it. It stays on one line and shrinks on narrow screens, and respects the bottom safe area. Without `navigatorObservers` (e.g. go_router) the line is shown on every screen. ## App icon quick actions ```dart await HomeActions.init( items: HomeActions.items(online: true, tr: myTranslate), onAction: (type) { switch (type) { case HomeActions.continueGame: resume(); case HomeActions.friends: openFriends(); case HomeActions.share: shareApp(); // the app opens the share sheet itself } }, ); ``` Custom items, or items from JSON / remote config: ```dart await HomeActions.init( items: [ const HomeAction('new_note', 'New note', icon: 'ic_note'), const HomeAction('search', 'Search'), ], onAction: handle, ); final items = HomeActions.parse(jsonDecode(raw) as List); // invalid and duplicate items are dropped, max 4 ``` Calling `init` again updates the labels (for example after a language change); the handler is installed once. `HomeActions.clear()` removes all items. **Native setup.** None is needed for text-only items. For `icon`, add an image asset with that name to `ios/Runner/Assets.xcassets` and a drawable with the same name to `android/app/src/main/res/drawable/`. ## Home-screen widgets ```dart final widgets = HomeWidgets( appGroup: 'group.com.example.app', // iOS App Group iosKinds: const ['HomeSnapshotWidget'], // WidgetKit kinds androidProviders: const ['com.example.app.HomeSnapshotWidgetProvider'], ); await widgets.init( onOpen: (tab) => goToTab(tab), // myapp://tab/2 onAction: (action) { // myapp://play if (action == 'play') startRound(); }, ); await widgets.show(const HomeSnapshot( title: 'Snake', record: 42, streak: 3, rewardReady: true, recordLabel: 'Best', // all labels can be translated )); // or any flat data for your own widget layout: await widgets.update({'title': 'Notes', 'count': '12'}); ``` `HomeSnapshot.keys` lists the keys the native templates read. `HomeWidgetLink.tabFrom` / `actionFrom` parse tap URLs if you handle links yourself. ### iOS setup 1. In Xcode: *File → New → Target → Widget Extension*. 2. Add the same **App Group** (e.g. `group.com.example.app`) to both the Runner and the widget target (*Signing & Capabilities → App Groups*). 3. Copy [`native/ios/HomeSnapshotWidget.swift`](native/ios/HomeSnapshotWidget.swift) into the extension and set `APP_GROUP` and `URL_SCHEME`. Register `HomeSnapshotWidget()` in the extension's `@main` `WidgetBundle`. 4. Register the URL scheme in `ios/Runner/Info.plist` so taps open the app: ```xml CFBundleURLTypes CFBundleURLSchemes myapp ``` See the [`home_widget` iOS guide](https://pub.dev/packages/home_widget#ios) for details. ### Android setup 1. Copy [`HomeSnapshotWidgetProvider.kt`](native/android/HomeSnapshotWidgetProvider.kt) next to your `MainActivity.kt`; set the package and `URL_SCHEME`. 2. Copy [`home_snapshot_widget.xml`](native/android/home_snapshot_widget.xml) to `res/layout/` and [`home_snapshot_widget_info.xml`](native/android/home_snapshot_widget_info.xml) to `res/xml/`. 3. Register the receiver in `AndroidManifest.xml` inside ``: ```xml ``` 4. To receive taps, add to the `MainActivity` ``: ```xml ``` ## Example See [`example/`](example/) for a minimal app using all three features. ## License MIT, see [LICENSE](LICENSE).