Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 2 additions & 61 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,4 @@
## 1.0.0
- chore: bump minimum Dart SDK version to 3.7
- chore: bump `extended_image` to `^10.0.1`
- chore: bump `provider` to `^6.1.5+1`

## 0.1.2

- fix: the endless loop can still happen if you switch between tabs quickly and time it perfectly while still loading gifs.

[All Code Changes](https://github.com/Flyclops/tenor_flutter/compare/0.1.1...0.1.2)

## 0.1.1

- fix: if you switch tabs very quickly before the initial gif fetch then you will get stuck in an endless loop and crash the app.

[All Code Changes](https://github.com/Flyclops/tenor_flutter/compare/0.1.0...0.1.1)

## 0.1.0

- feat: Integrate [tenor_dart's](https://pub.dev/packages/tenor_dart) new `TenorResult.source` parameter to track which tab the GIF was selected from for analytics
- fix: not being able to scroll down to load more on tablets or when using display zoom on iPad
- refactor: `TenorViewEmojis`, `TenorViewGifs`, `TenorViewStickers` and `TenorTabView` now have a `gifsPerRow` parameter instead of `mediaWidth` to be more explicit and support a wider range of devices

[All Code Changes](https://github.com/Flyclops/tenor_flutter/compare/0.0.5...0.1.0)

## 0.0.5

- fix: error when only one tab is passed in

[All Code Changes](https://github.com/Flyclops/tenor_flutter/compare/0.0.4...0.0.5)

## 0.0.4

- feature: add `coverAppBar` _(false)_ to disable calculations preventing bottom sheet from covering AppBar
- refactor: expose `animationStyle` as a parameter of `TenorStyle`
- refactor: expose `initialExtent` as a parameter of `showAsBottomSheet()`, defaults to `maxExtent` if not used
- refactor: expose `snapSizes` as a parameter of `showAsBottomSheet()`
- refactor: expose `useSafeArea` as a parameter of `showAsBottomSheet()`

[All Code Changes](https://github.com/Flyclops/tenor_flutter/compare/0.0.3...0.0.4)

## 0.0.3

- chore: write tests
- chore: updated/added examples and broke them up for a better experience
- fix: category was displaying `searchTerm` and now it's displaying `name` as that is localized from Tenor
- added `stripHashtag` _(true)_ to `TenorCategoryStyle` so you can display a hashtag before each category name if you'd like _(comes like that from Tenor)_
- fix: issue where featured category could not be localized
- refactor: expose `keyboardDismissBehavior` as a parameter of `showAsBottomSheet()`
- refactor: expose `searchFieldHintText` as a parameter of `showAsBottomSheet()` to make localization easier

[All Code Changes](https://github.com/Flyclops/tenor_flutter/compare/0.0.2...0.0.3)

## 0.0.2

- chore: write tests
- refactor: support `tenor_dart` changes

[All Code Changes](https://github.com/Flyclops/tenor_flutter/compare/0.0.1...0.0.2)

## 0.0.1

- Initial version
- refactor: [klipy_flutter](https://pub.dev/packages/klipy_flutter) so that it supports the KLIPY API via their [migration docs](https://docs.klipy.com/migrate-from-tenor).
- BREAKING: `contentFilter` has been removed and can be set via the [Partner Panel](https://docs.klipy.com/migrate-from-tenor/content-filtering)
69 changes: 34 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,84 @@
# Tenor Flutter
# KLIPY Flutter

<p align="center">
<a href="https://pub.dartlang.org/packages/tenor_flutter"><img src="https://img.shields.io/pub/v/tenor_flutter.svg" alt="Tenor Flutter Pub Package" /></a>
<a href="https://github.com/Flyclops/tenor_flutter/actions/workflows/main.yml"><img src="https://github.com/flyclops/tenor_flutter/actions/workflows/main.yml/badge.svg" alt="Build Status" /></a>
<a href="https://coveralls.io/github/Flyclops/tenor_flutter?branch=main"><img src="https://coveralls.io/repos/github/Flyclops/tenor_flutter/badge.svg?branch=main" alt="Coverage Status" /></a>
<a href="https://github.com/flyclops/tenor_flutter/stargazers"><img src="https://img.shields.io/github/stars/flyclops/tenor_flutter?style=flat" alt="Tenor Dart Stars" /></a>
<a href="https://github.com/Flyclops/tenor_flutter/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-BSD_3--Clause-blue.svg" alt="License BSD 3-Clause" /></a>
<a href="https://pub.dartlang.org/packages/klipy_flutter"><img src="https://img.shields.io/pub/v/klipy_flutter.svg" alt="KLIPY Flutter Pub Package" /></a>
<a href="https://github.com/Flyclops/klipy_flutter/actions/workflows/main.yml"><img src="https://github.com/flyclops/klipy_flutter/actions/workflows/main.yml/badge.svg" alt="Build Status" /></a>
<a href="https://coveralls.io/github/Flyclops/klipy_flutter?branch=main"><img src="https://coveralls.io/repos/github/Flyclops/klipy_flutter/badge.svg?branch=main" alt="Coverage Status" /></a>
<a href="https://github.com/flyclops/klipy_flutter/stargazers"><img src="https://img.shields.io/github/stars/flyclops/klipy_flutter?style=flat" alt="KLIPY Dart Stars" /></a>
<a href="https://github.com/Flyclops/klipy_flutter/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-BSD_3--Clause-blue.svg" alt="License BSD 3-Clause" /></a>
</p>

This package integrates [Tenor GIF search](https://tenor.com/) into [Flutter](https://flutter.dev/) by utilizing the [tenor_dart](https://pub.dev/packages/tenor_dart) package to communicate directly with the [Tenor API V2](https://developers.google.com/tenor/guides/quickstart) via [http](https://pub.dev/packages/http).
This package integrates [KLIPY GIF search](https://klipy.com/) into [Flutter](https://flutter.dev/) by utilizing the [klipy_dart](https://pub.dev/packages/klipy_dart) package to communicate directly with the [KLIPY API](https://docs.klipy.com/getting-started) via [http](https://pub.dev/packages/http). We are currently using the [migration from Tenor](https://docs.klipy.com/migrate-from-tenor) option but plan to build this package out to be feature complete with the KLIPY API.

The package currently provides an opinionated yet customizable UI experience for searching and selecting from a list of GIFs/Stickers from the Tenor GIF search API.
The package currently provides an opinionated yet customizable UI experience for searching and selecting from a list of GIFs/Stickers from the KLIPY GIF search API.

<p align="center"><img src="https://github.com/flyclops/tenor_flutter/raw/main/example/assets/demo.gif" width="200" alt="Tenor Flutter Demo"/></p>
<p align="center"><img src="https://github.com/flyclops/klipy_flutter/raw/main/example/assets/demo.gif" width="200" alt="KLIPY Flutter Demo"/></p>

<p align="center"><strong><sup>Show some ❤️ and <a href="https://github.com/flyclops/tenor_flutter">star the repo</a> to support this package.</sup></strong></p>
<p align="center"><strong><sup>Show some ❤️ and <a href="https://github.com/flyclops/klipy_flutter">star the repo</a> to support this package.</sup></strong></p>

## What to know

- In order to start using Tenor Flutter you must obtain an API key by registering your project with [Tenor](https://developers.google.com/tenor/guides/quickstart).
- Tenor requires proper [attribution](https://developers.google.com/tenor/guides/attribution) for projects using their API. This package enables "Powered By Tenor" and "Search Tenor" by default. You are only required to have one.
- In order to start using KLIPY Dart you must obtain an API key by registering your project with [KLIPY](https://docs.klipy.com/getting-started).
- KLIPY requires proper [attribution](https://docs.klipy.com/attribution) for projects using their API. This package does not handle the attribution process, so you will need to take care of it yourself.

## Obtaining Tenor API v2 key
## Obtaining KLIPY API key

1. Log in to the [Google Cloud Console](https://console.cloud.google.com)
2. Create a [new project](https://console.cloud.google.com/projectcreate)
3. Go to the Google Cloud Marketplace and find the [Tenor API](https://console.cloud.google.com/marketplace/product/google/tenor.googleapis.com)
4. Click `Enable` to activate it
5. In the navigation menu, go to the `APIs & Services` tab and select [Credentials](https://console.cloud.google.com/apis/credentials)
6. Click `+ Create Credentials` and choose `API key`
7. Copy the generated API key
8. Provide this API key as a parameter to `Tenor(apiKey: 'YOUR_API_KEY')`
1. Log in to the [partner panel](https://partner.klipy.com)
2. Add a [new platform](https://partner.klipy.com/api-keys)
3. Click `Create Key`
4. Copy the generated API key
5. Provide this API key as a parameter to `KlipyClient(apiKey: 'YOUR_API_KEY')`

## Usage

### Installation

```
flutter pub add tenor_flutter
flutter pub add klipy_flutter
```

<sup>Having trouble? Read the pub.dev <a href="https://pub.dev/packages/tenor_flutter/install">installation page</a>.</sup>
<sup>Having trouble? Read the pub.dev <a href="https://pub.dev/packages/klipy_flutter/install">installation page</a>.</sup>

### Import

Import the package into the dart file where it will be used:

```
import 'package:tenor_flutter/tenor_flutter.dart';
import 'package:klipy_flutter/klipy_flutter.dart';
```

### Initialize

You must pass in a valid `apiKey` provided by [Tenor](https://developers.google.com/tenor/guides/quickstart). It's **strongly recommended** to also pass in a `clientKey` as this will help you distinguish which project is making the requests.
You must pass in a valid `apiKey` provided by [KLIPY](https://docs.klipy.com/getting-started).

If you would like to distinguish between projects/devices then consider creating seperate [API keys](https://partner.klipy.com/api-keys) under the same platform.

```
final tenorClient = Tenor(apiKey: 'YOUR_API_KEY', clientKey: 'YOUR_PROJECT_NAME');
final klipyClient = KlipyClient(apiKey: 'YOUR_API_KEY');
```

## Example

For more elaborate examples feel free to check out [example/lib/main.dart](https://github.com/Flyclops/tenor_flutter/blob/main/example/lib/main.dart).
For more elaborate examples feel free to check out [example/lib/main.dart](https://github.com/Flyclops/klipy_flutter/blob/main/example/lib/main.dart).

Here's how to display the UI as a bottom sheet and then print the user's selection. If `null` is returned, it means the user closed the sheet without choosing a GIF.

```
final tenorClient = Tenor(apiKey: 'YOUR_API_KEY', clientKey: 'YOUR_PROJECT_NAME');
final TenorResult? result = await tenorClient.showAsBottomSheet(context: context);
final klipyClient = KlipyClient(apiKey: 'YOUR_API_KEY');
final KlipyResultObject? result = await klipyClient.showAsBottomSheet(context: context);
print(result?.media.tinyGif?.url);
```

## Don't need the UI?

If you're seeking a solution that allows for full customization without the need of dependencies then consider [Tenor Dart](https://github.com/Flyclops/tenor_dart).
If you're seeking a solution that allows for full customization without the need of dependencies then consider [KLIPY Dart](https://github.com/Flyclops/klipy_dart).

## Sponsors

<table>
<tr>
<td><p align="center"><a href="https://flyclops.com/"><img src="https://github.com/Flyclops/tenor_flutter/blob/main/example/assets/flyclops_logo_github.png?raw=true" alt="Flyclops"/></a></p></td>
<td><p align="center"><a href="https://flyclops.com/games/domino.html"><img src="https://github.com/Flyclops/tenor_flutter/blob/main/example/assets/domino_logo_github.png?raw=true" alt="Domino!"/></a></p></td>
<td><p align="center"><a href="https://flyclops.com/"><img src="https://github.com/Flyclops/klipy_flutter/blob/main/example/assets/flyclops_logo_github.png?raw=true" alt="Flyclops"/></a></p></td>
<td><p align="center"><a href="https://flyclops.com/games/domino.html"><img src="https://github.com/Flyclops/klipy_flutter/blob/main/example/assets/domino_logo_github.png?raw=true" alt="Domino!"/></a></p></td>
</tr>
<tr>
<td><p align="center"><a href="https://flyclops.com/">Flyclops</a> is a independent mobile games studio specializing in casual multi-player games, both asynchronous turn-based, and real-time. Flyclops’s games have been played by millions across&nbsp;the&nbsp;globe.</p></td>
Expand All @@ -90,14 +89,14 @@ If you're seeking a solution that allows for full customization without the need
## What's next?

- Documentation
- Tests _([Contributions](https://github.com/Flyclops/tenor_flutter/blob/main/CONTRIBUTING.md) welcome)_ ^\_^
- Tests _([Contributions](https://github.com/Flyclops/klipy_flutter/blob/main/CONTRIBUTING.md) welcome)_ ^\_^
- Further improvements

## Contributing

If you read this far then you are awesome! There are a multiple ways in which you can [contribute](https://github.com/Flyclops/tenor_flutter/blob/main/CONTRIBUTING.md):
If you read this far then you are awesome! There are a multiple ways in which you can [contribute](https://github.com/Flyclops/klipy_flutter/blob/main/CONTRIBUTING.md):

- Pick up any issue marked with "[good first issue](https://github.com/flyclops/tenor_flutter/issues?q=is:open+is:issue+label:%22good+first+issue%22)"
- Pick up any issue marked with "[good first issue](https://github.com/flyclops/klipy_flutter/issues?q=is:open+is:issue+label:%22good+first+issue%22)"
- Propose any feature, enhancement
- Report a bug
- Fix a bug
Expand Down
Binary file added assets/media_watermark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/powered_by_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/powered_by_light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Tenor Flutter Example
# KLIPY Flutter Example

If you want to test this example create a `.env` file located at `example/.env` with your [Tenor API](https://developers.google.com/tenor/guides/quickstart) key `TENOR_API_KEY=PUT_YOUR_KEY_HERE` and then run `example/lib/main.dart`.
If you want to test this example create a `.env` file located at `example/.env` with your [KLIPY API](https://docs.klipy.com/getting-started) key `KLIPY_API_KEY=PUT_YOUR_KEY_HERE` and then run `example/lib/main.dart`.
Binary file modified example/assets/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/assets/domino_logo_github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/assets/flyclops_logo_github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 23 additions & 23 deletions example/lib/examples/dark_theme.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_config/flutter_config.dart';
import 'package:tenor_flutter/tenor_flutter.dart';
import 'package:klipy_flutter/klipy_flutter.dart';

class DarkTheme extends StatefulWidget {
const DarkTheme({super.key});
Expand All @@ -10,10 +10,10 @@ class DarkTheme extends StatefulWidget {
}

class DarkThemeState extends State<DarkTheme> {
// replace apiKey with an api key provided by Tenor > https://developers.google.com/tenor/guides/quickstart
var tenor = Tenor(apiKey: FlutterConfig.get('TENOR_API_KEY'));
// replace apiKey with an api key provided by KLIPY > https://docs.klipy.com/getting-started
var klipyClient = KlipyClient(apiKey: FlutterConfig.get('KLIPY_API_KEY'));
// define a result that we can display later
TenorResult? selectedResult;
KlipyResultObject? selectedResult;

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -44,11 +44,11 @@ class DarkThemeState extends State<DarkTheme> {
FloatingActionButton(
backgroundColor: Colors.black,
onPressed: () async {
final result = await tenor.showAsBottomSheet(
final result = await klipyClient.showAsBottomSheet(
context: context,
style: TenorStyle(
style: KlipyStyle(
color: const Color(0xFF2b2d31),
searchFieldStyle: const TenorSearchFieldStyle(
searchFieldStyle: const KlipySearchFieldStyle(
fillColor: Color(0xFF1e1f22),
hintStyle: TextStyle(
color: Color(0xFFb5bac1),
Expand All @@ -61,10 +61,10 @@ class DarkThemeState extends State<DarkTheme> {
fontWeight: FontWeight.normal,
),
),
attributionStyle: const TenorAttributionStyle(
attributionStyle: const KlipyAttributionStyle(
brightnes: Brightness.dark,
),
tabBarStyle: TenorTabBarStyle(
tabBarStyle: KlipyTabBarStyle(
decoration: BoxDecoration(
color: const Color(0xFF1e1f22),
border: Border.all(
Expand All @@ -85,7 +85,7 @@ class DarkThemeState extends State<DarkTheme> {
unselectedLabelColor: const Color(0xFFb5bac1),
labelColor: Colors.white,
),
selectedCategoryStyle: const TenorSelectedCategoryStyle(
selectedCategoryStyle: const KlipySelectedCategoryStyle(
icon: Icon(
Icons.arrow_back_ios_new,
size: 15,
Expand All @@ -97,35 +97,35 @@ class DarkThemeState extends State<DarkTheme> {
fontWeight: FontWeight.normal,
),
),
tabViewStyle: const TenorTabViewStyle(
tabViewStyle: const KlipyTabViewStyle(
mediaBackgroundColor: Color(0xFF404249),
),
),
tabs: [
TenorTab(
KlipyTab(
name: 'Emojis',
view: TenorViewEmojis(
client: tenor,
style: const TenorTabViewStyle(
view: KlipyViewEmojis(
client: klipyClient,
style: const KlipyTabViewStyle(
mediaBackgroundColor: Color(0xFF404249),
),
),
),
TenorTab(
KlipyTab(
name: 'GIFs',
view: TenorViewGifs(
client: tenor,
style: const TenorTabViewStyle(
view: KlipyViewGifs(
client: klipyClient,
style: const KlipyTabViewStyle(
mediaBackgroundColor: Color(0xFF404249),
),
featuredCategory: '📈 Featured22',
),
),
TenorTab(
KlipyTab(
name: 'Stickers',
view: TenorViewStickers(
client: tenor,
style: const TenorTabViewStyle(
view: KlipyViewStickers(
client: klipyClient,
style: const KlipyTabViewStyle(
mediaBackgroundColor: Color(0xFF404249),
),
),
Expand Down
Loading