{"id":13396062,"url":"https://github.com/pyricau/frenchtoast","last_synced_at":"2025-09-19T19:18:39.167Z","repository":{"id":140899973,"uuid":"41701898","full_name":"pyricau/frenchtoast","owner":"pyricau","description":"Stale Android Toasts made tasty.","archived":false,"fork":false,"pushed_at":"2018-10-24T15:39:57.000Z","size":1597,"stargazers_count":364,"open_issues_count":2,"forks_count":40,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-05-19T20:09:29.337Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pyricau.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-08-31T21:35:59.000Z","updated_at":"2025-05-02T16:30:09.000Z","dependencies_parsed_at":"2024-01-27T10:01:10.795Z","dependency_job_id":"d47ab986-ed89-45c5-8e23-c9e8f784322e","html_url":"https://github.com/pyricau/frenchtoast","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/pyricau/frenchtoast","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyricau%2Ffrenchtoast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyricau%2Ffrenchtoast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyricau%2Ffrenchtoast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyricau%2Ffrenchtoast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pyricau","download_url":"https://codeload.github.com/pyricau/frenchtoast/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyricau%2Ffrenchtoast/sbom","scorecard":{"id":751830,"data":{"date":"2025-08-11","repo":{"name":"github.com/pyricau/frenchtoast","commit":"a1fbc59f7f66f33f9e596c123db266c66a4e5de6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":2,"reason":"Found 5/19 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: gradle/wrapper/gradle-wrapper.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 6 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T20:35:47.878Z","repository_id":140899973,"created_at":"2025-08-22T20:35:47.878Z","updated_at":"2025-08-22T20:35:47.878Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275989946,"owners_count":25565652,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-19T02:00:09.700Z","response_time":108,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T18:00:38.743Z","updated_at":"2025-09-19T19:18:39.137Z","avatar_url":"https://github.com/pyricau.png","language":"Java","funding_links":[],"categories":["Index `(light-weight pages)`","Java","Index"],"sub_categories":[],"readme":"# FrenchToast\n\n*Stale Android Toasts made tasty.*\n\nAndroid Toasts are amazing, but they have a few major drawbacks:\n\n* You cannot control **when they show up** as well as their **duration**. Other apps can enqueue toasts that will delay yours from showing up. \n* They [break context](http://cyrilmottier.com/2012/07/24/the-making-of-prixing-4-activity-tied-notifications/): they remain on screen when the user switches to other activities.\n* The API is error prone: `Toast.makeText(context, \"Important Toast\", LENGTH_LONG); // Don't forget show()!`\n\nFrenchToast gives you absolute control over your app Toasts. It does so by duplicating the internals of Android Toasts and giving you access.\n\nUnlike other *Toast-like* libraries, FrenchToast doesn't add a view to the root of your activity. Instead, it creates a new Window for each Toast, exactly like the real Android Toasts.\n\n![demo.gif](assets/demo.gif)\n\n## Getting Started\n\nIn your `build.gradle`:\n\n```gradle\n dependencies {\n   implementation 'info.piwai.frenchtoast:frenchtoast:1.0'\n }\n```\n\nYou need to setup `FrenchToast` in your `Application` class:\n\n```java\npublic class ExampleApplication extends Application {\n\n  @Override public void onCreate() {\n    super.onCreate();\n    FrenchToast.install(this);\n  }\n}\n```\n\nYou are ready to Toast!\n\n```java\nFrenchToast.with(context).showText(\"I love Baguettes!\");\n```\n\nA `FrenchToast`:\n\n* **hides** when the Activity is **paused**,\n* shows again when it's resumed,\n* has a default duration of `Toast.LENGTH_LONG`,\n* **survives configuration changes**,\n* is **queued**, so that only one Toast shows at once.\n\nYou can customize the default duration:\n\n```java\nFrenchToast.with(context).shortLength().showText(R.string.short_bread);\n\nFrenchToast.with(context).longLength().showText(R.string.long_bread);\n\nFrenchToast.with(context).length(3, SECONDS).showText(R.string.bespoke_bread);\n```\n\nThe duration of a Toast resets when the activity is paused / resumed, to make sure the user had enough time to see the Toast.\n\n## Bespoke Toasts\n\nA Toast can be created from a layout:\n\n```java\nFrenchToast.with(context).showLayout(R.layout.toasted_baguette);\n```\n\nYou can also dip an Android Toast:\n\n```java\nToast toast = Toast.makeText(context, \"BREAD ALL THE THINGS!\", LENGTH_SHORT);\ntoast.setGravity(LEFT | TOP, 0, 0);\nFrenchToast.with(context).showDipped(toast);\n```\n\n## Unplugging the Toaster\n\nA Toast can be canceled:\n\n```\nToasted toasted = FrenchToast.with(context).showText(\"I love Baguettes!\");\n// I'd rather show a Bagel.\ntoasted.cancel();\n```\n\nYou can also clear all queued Toasts for a given Activity:\n\n```java\nFrenchToast.with(context).clear();\n```\n\n## Context vs Activity\n\n`FrenchToast.with()` takes a Context, however it expects that `Context` to be an `Activity` or to wrap an `Activity`, because FrenchToast keeps one `ToastQueue` for each activity.\n\n## Crafting your own Mixture\n\nIf you want more control over when to show / hide Toasts, you can directly use `Mixture`:\n\n```java\nToast toast = Toast.makeText(context, \"BREAD ALL THE THINGS!\", LENGTH_SHORT);\nMixture mixture = Mixture.dip(toast);\n// The Toast is shown forever, as long as the process lives:\nmixture.show();\n// Or until you call hide:\nmixture.hide();\n```\n\n## FAQ\n\n### What's up with the strange names?\n\nA **French toast** is a dish made of bread **dipped** in a **mixture** of beaten eggs and then fried.\n\n### Is this a serious project?\n\nYes. Despite the puns, this code is production ready. It is heavily inspired from [android.widget.Toast](https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/Toast.java).\n\n### What's the minimum supported Android?\n\nFrenchToast requires a **minimum SDK version of 14** or above, because it uses [Application.ActivityLifecycleCallbacks](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).\n\n### Why reimplement Toast?\n\nBecause we can have better Toasts, so we should.\n\nI read the source of `Toast` when I was flying back, still under a creative influence of Droidcon NYC. I realized it could be done, so I wrote FrenchToast.\n\n![logo.png](assets/logo.png)\n\n## License\n\n    Copyright 2015 Pierre-Yves Ricau\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyricau%2Ffrenchtoast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpyricau%2Ffrenchtoast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyricau%2Ffrenchtoast/lists"}