├── .media └── example.png ├── test └── api │ ├── mocks │ ├── mock_twitter_client.dart │ └── mock_twitter_client.mocks.dart │ ├── trends │ ├── data │ │ ├── trends_closest_response.json │ │ └── trends_available_response.json │ └── trends_service_test.dart │ ├── lists │ ├── lists_service_test.dart │ └── data │ │ └── list.json │ └── tweets │ ├── data │ ├── statuses_destroy.json │ ├── statuses_update.json │ ├── favorites_create.json │ ├── favorites_destroy.json │ ├── statuses_unretweet.json │ ├── statuses_show.json │ └── statuses_retweets_of_me.json │ └── tweet_service_test.dart ├── analysis_options.yaml ├── .gitignore ├── lib ├── api │ ├── direct_messages │ │ └── direct_messages_service.dart │ ├── trends │ │ ├── data │ │ │ ├── trend.dart │ │ │ ├── trends.dart │ │ │ ├── trend.g.dart │ │ │ ├── trends.g.dart │ │ │ ├── trend_location.dart │ │ │ └── trend_location.g.dart │ │ └── trends_service.dart │ ├── tweets │ │ ├── data │ │ │ ├── current_user_retweet.dart │ │ │ ├── current_user_retweet.g.dart │ │ │ ├── quoted_status_permalink.g.dart │ │ │ ├── quoted_status_permalink.dart │ │ │ ├── tweet_search.dart │ │ │ ├── tweet_search.g.dart │ │ │ ├── tweet.g.dart │ │ │ └── tweet.dart │ │ └── tweet_search_service.dart │ ├── users │ │ └── data │ │ │ ├── derived.dart │ │ │ ├── paginated_ids.dart │ │ │ ├── paginated_users.dart │ │ │ ├── derived.g.dart │ │ │ ├── paginated_ids.g.dart │ │ │ ├── friendship.g.dart │ │ │ ├── relationship_entity.dart │ │ │ ├── user_entities.dart │ │ │ ├── paginated_users.g.dart │ │ │ ├── relationship.dart │ │ │ ├── location.g.dart │ │ │ ├── friendship.dart │ │ │ ├── user_entities.g.dart │ │ │ ├── relationship.g.dart │ │ │ ├── banner.dart │ │ │ ├── location.dart │ │ │ ├── relationship_entity.g.dart │ │ │ ├── banner.g.dart │ │ │ ├── user.g.dart │ │ │ └── user.dart │ ├── common │ │ └── data │ │ │ ├── option.dart │ │ │ ├── option.g.dart │ │ │ ├── symbol.g.dart │ │ │ ├── hashtag.g.dart │ │ │ ├── poll.dart │ │ │ ├── url.g.dart │ │ │ ├── user_mention.g.dart │ │ │ ├── poll.g.dart │ │ │ ├── symbol.dart │ │ │ ├── hashtag.dart │ │ │ ├── user_mention.dart │ │ │ ├── url.dart │ │ │ ├── entities.dart │ │ │ ├── edit_control.dart │ │ │ ├── entities.g.dart │ │ │ └── edit_control.g.dart │ ├── media │ │ ├── data │ │ │ ├── additional_media_info.dart │ │ │ ├── size.g.dart │ │ │ ├── size.dart │ │ │ ├── video_info.dart │ │ │ ├── additional_media_info.g.dart │ │ │ ├── sizes.g.dart │ │ │ ├── sizes.dart │ │ │ ├── video_info.g.dart │ │ │ ├── media.g.dart │ │ │ ├── media_upload.dart │ │ │ ├── media_upload.g.dart │ │ │ └── media.dart │ │ └── media_service.dart │ ├── lists │ │ └── data │ │ │ ├── paginated_twitter_lists.dart │ │ │ ├── twitter_list.dart │ │ │ ├── paginated_twitter_lists.g.dart │ │ │ └── twitter_list.g.dart │ ├── geo │ │ └── data │ │ │ ├── coordinates.dart │ │ │ ├── coordinates.g.dart │ │ │ ├── bounding_box.g.dart │ │ │ ├── bounding_box.dart │ │ │ ├── place.g.dart │ │ │ └── place.dart │ ├── abstract_twitter_client.dart │ └── twitter_client.dart ├── src │ ├── utils │ │ ├── isolates.dart │ │ ├── _isolates_web.dart │ │ ├── map_utils.dart │ │ ├── date_utils.dart │ │ └── _isolates_io.dart │ ├── annotations.dart │ └── twitter_api_base.dart └── twitter_api.dart ├── .github └── workflows │ └── dart.yml ├── pubspec.yaml ├── example └── main.dart ├── LICENSE ├── CHANGELOG.md └── README.md /.media/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertodoering/twitter_api/HEAD/.media/example.png -------------------------------------------------------------------------------- /test/api/mocks/mock_twitter_client.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_twitter_api/twitter_api.dart'; 2 | import 'package:mockito/annotations.dart'; 3 | 4 | @GenerateMocks([TwitterClient]) 5 | void main() {} 6 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Defines a default set of lint rules enforced for 2 | # projects at Google. For details and rationale, 3 | # see https://github.com/dart-lang/pedantic#enabled-lints. 4 | include: package:pedantic/analysis_options.yaml 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | 5 | pubspec.lock 6 | 7 | # Conventional directory for build outputs 8 | build/ 9 | 10 | # Directory created by dartdoc 11 | doc/api/ 12 | 13 | # intellij 14 | .idea/ 15 | -------------------------------------------------------------------------------- /lib/api/direct_messages/direct_messages_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_twitter_api/twitter_api.dart'; 2 | 3 | class DirectMessagesService { 4 | const DirectMessagesService({ 5 | required this.client, 6 | }); 7 | 8 | final AbstractTwitterClient client; 9 | } 10 | -------------------------------------------------------------------------------- /lib/src/utils/isolates.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | /// Signature for the callback passed to [compute]. 4 | /// 5 | /// Instances of [ComputeCallback] must be top-level functions or static methods 6 | /// of classes, not closures or instance methods of objects. 7 | typedef ComputeCallback = FutureOr Function(Q message); 8 | -------------------------------------------------------------------------------- /test/api/trends/data/trends_closest_response.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "country": "Australia", 4 | "countryCode": "AU", 5 | "name": "Australia", 6 | "parentid": 1, 7 | "placeType": { 8 | "code": 12, 9 | "name": "Country" 10 | }, 11 | "url": "http://where.yahooapis.com/v1/place/23424748", 12 | "woeid": 23424748 13 | } 14 | ] -------------------------------------------------------------------------------- /lib/src/annotations.dart: -------------------------------------------------------------------------------- 1 | class _NotImplemented { 2 | const _NotImplemented(); 3 | } 4 | 5 | /// The annotation `@notImplemented` marks a method or parameter as (currently) 6 | /// not implemented or supported. 7 | /// 8 | /// If a parameter is not implemented, it may be used in the request but any 9 | /// consequent changes of the response are likely not handled. 10 | const Object notImplemented = _NotImplemented(); 11 | -------------------------------------------------------------------------------- /lib/src/utils/_isolates_web.dart: -------------------------------------------------------------------------------- 1 | import 'isolates.dart'; 2 | 3 | /// The dart:html implementation of [compute]. 4 | Future compute(ComputeCallback callback, Q message) async { 5 | // To avoid blocking the UI immediately for an expensive function call, we 6 | // pump a single frame to allow the framework to complete the current set 7 | // of work. 8 | await null; 9 | return callback(message); 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/dart.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | container: 15 | image: google/dart:latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Install dependencies 20 | run: pub get 21 | - name: Run tests 22 | run: pub run test 23 | -------------------------------------------------------------------------------- /lib/src/utils/map_utils.dart: -------------------------------------------------------------------------------- 1 | extension ParameterExtension on Map { 2 | /// Adds an entry to the map. 3 | /// 4 | /// If [value] is `null`, it is not added to the map. 5 | /// If [value] is a [List], the list is joined with a `,`. 6 | /// Else, the [value.toString()] is used. 7 | void addParameter(String param, dynamic value) { 8 | if (value is List) { 9 | this[param] = value.join(','); 10 | } else if (value != null) { 11 | this[param] = '$value'; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/api/trends/data/trend.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'trend.g.dart'; 4 | 5 | @JsonSerializable( 6 | explicitToJson: true, 7 | fieldRename: FieldRename.snake, 8 | ) 9 | class Trend { 10 | Trend(); 11 | 12 | factory Trend.fromJson(Map json) => _$TrendFromJson(json); 13 | 14 | String? name; 15 | String? url; 16 | dynamic promotedContent; 17 | String? query; 18 | int? tweetVolume; 19 | 20 | Map toJson() => _$TrendToJson(this); 21 | } 22 | -------------------------------------------------------------------------------- /lib/api/tweets/data/current_user_retweet.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'current_user_retweet.g.dart'; 4 | 5 | @JsonSerializable( 6 | explicitToJson: true, 7 | fieldRename: FieldRename.snake, 8 | ) 9 | class CurrentUserRetweet { 10 | CurrentUserRetweet(); 11 | 12 | factory CurrentUserRetweet.fromJson(Map json) => 13 | _$CurrentUserRetweetFromJson(json); 14 | 15 | String? idStr; 16 | 17 | Map toJson() => _$CurrentUserRetweetToJson(this); 18 | } 19 | -------------------------------------------------------------------------------- /lib/api/users/data/derived.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_twitter_api/api/users/data/location.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'derived.g.dart'; 5 | 6 | @JsonSerializable( 7 | explicitToJson: true, 8 | fieldRename: FieldRename.snake, 9 | ) 10 | class Derived { 11 | Derived(); 12 | 13 | factory Derived.fromJson(Map json) => 14 | _$DerivedFromJson(json); 15 | 16 | List? locations; 17 | 18 | Map toJson() => _$DerivedToJson(this); 19 | } 20 | -------------------------------------------------------------------------------- /lib/api/common/data/option.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'option.g.dart'; 4 | 5 | @JsonSerializable( 6 | explicitToJson: true, 7 | fieldRename: FieldRename.snake, 8 | ) 9 | class Option { 10 | Option(); 11 | 12 | factory Option.fromJson(Map json) => _$OptionFromJson(json); 13 | 14 | /// The poll position for this option. 15 | int? position; 16 | 17 | /// The text of this poll option. 18 | String? text; 19 | 20 | Map toJson() => _$OptionToJson(this); 21 | } 22 | -------------------------------------------------------------------------------- /lib/api/users/data/paginated_ids.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'paginated_ids.g.dart'; 4 | 5 | @JsonSerializable( 6 | explicitToJson: true, 7 | fieldRename: FieldRename.snake, 8 | ) 9 | class PaginatedIds { 10 | PaginatedIds(); 11 | 12 | factory PaginatedIds.fromJson(Map json) => 13 | _$PaginatedIdsFromJson(json); 14 | 15 | List? ids; 16 | String? previousCursorStr; 17 | String? nextCursorStr; 18 | 19 | Map toJson() => _$PaginatedIdsToJson(this); 20 | } 21 | -------------------------------------------------------------------------------- /lib/api/media/data/additional_media_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'additional_media_info.g.dart'; 4 | 5 | @JsonSerializable( 6 | explicitToJson: true, 7 | fieldRename: FieldRename.snake, 8 | ) 9 | class AdditionalMediaInfo { 10 | AdditionalMediaInfo(); 11 | 12 | factory AdditionalMediaInfo.fromJson(Map json) => 13 | _$AdditionalMediaInfoFromJson(json); 14 | 15 | String? title; 16 | 17 | String? description; 18 | 19 | bool? embeddable; 20 | 21 | bool? monetizable; 22 | 23 | Map toJson() => _$AdditionalMediaInfoToJson(this); 24 | } 25 | -------------------------------------------------------------------------------- /lib/api/users/data/paginated_users.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_twitter_api/api/users/data/user.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'paginated_users.g.dart'; 5 | 6 | @JsonSerializable( 7 | explicitToJson: true, 8 | fieldRename: FieldRename.snake, 9 | ) 10 | class PaginatedUsers { 11 | PaginatedUsers(); 12 | 13 | factory PaginatedUsers.fromJson(Map json) => 14 | _$PaginatedUsersFromJson(json); 15 | 16 | List? users; 17 | 18 | String? nextCursorStr; 19 | 20 | String? previousCursorStr; 21 | 22 | Map toJson() => _$PaginatedUsersToJson(this); 23 | } 24 | -------------------------------------------------------------------------------- /lib/api/common/data/option.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'option.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Option _$OptionFromJson(Map json) { 10 | return Option() 11 | ..position = json['position'] as int? 12 | ..text = json['text'] as String?; 13 | } 14 | 15 | Map _$OptionToJson(Option instance) => { 16 | 'position': instance.position, 17 | 'text': instance.text, 18 | }; 19 | -------------------------------------------------------------------------------- /lib/api/tweets/data/current_user_retweet.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'current_user_retweet.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | CurrentUserRetweet _$CurrentUserRetweetFromJson(Map json) { 10 | return CurrentUserRetweet()..idStr = json['id_str'] as String?; 11 | } 12 | 13 | Map _$CurrentUserRetweetToJson(CurrentUserRetweet instance) => 14 | { 15 | 'id_str': instance.idStr, 16 | }; 17 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dart_twitter_api 2 | description: A dart wrapper for using the Twitter API with well documented interfaces for every endpoint. 3 | version: 0.6.0 4 | homepage: https://github.com/robertodoering/twitter_api 5 | repository: https://github.com/robertodoering/twitter_api 6 | issue_tracker: https://github.com/robertodoering/twitter_api/issues 7 | 8 | environment: 9 | sdk: '>=3.0.0 <4.0.0' 10 | 11 | dependencies: 12 | http: ^1.2.2 13 | intl: ^0.20.0 14 | json_annotation: ^4.0.0 15 | oauth1: ^2.1.0 16 | 17 | dev_dependencies: 18 | build_runner: ^2.4.13 19 | json_serializable: ^6.8.0 20 | mockito: ^5.0.0 21 | pedantic: ^1.11.0 22 | test: ^1.16.5 23 | -------------------------------------------------------------------------------- /lib/api/media/data/size.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'size.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Size _$SizeFromJson(Map json) { 10 | return Size() 11 | ..w = json['w'] as int? 12 | ..h = json['h'] as int? 13 | ..resize = json['resize'] as String?; 14 | } 15 | 16 | Map _$SizeToJson(Size instance) => { 17 | 'w': instance.w, 18 | 'h': instance.h, 19 | 'resize': instance.resize, 20 | }; 21 | -------------------------------------------------------------------------------- /lib/api/lists/data/paginated_twitter_lists.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_twitter_api/twitter_api.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'paginated_twitter_lists.g.dart'; 5 | 6 | @JsonSerializable( 7 | explicitToJson: true, 8 | fieldRename: FieldRename.snake, 9 | ) 10 | class PaginatedTwitterLists { 11 | PaginatedTwitterLists(); 12 | 13 | factory PaginatedTwitterLists.fromJson(Map json) => 14 | _$PaginatedTwitterListsFromJson(json); 15 | 16 | List? lists; 17 | 18 | String? nextCursorStr; 19 | 20 | String? previousCursorStr; 21 | 22 | Map toJson() => _$PaginatedTwitterListsToJson(this); 23 | } 24 | -------------------------------------------------------------------------------- /lib/api/common/data/symbol.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'symbol.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Symbol _$SymbolFromJson(Map json) { 10 | return Symbol() 11 | ..indices = 12 | (json['indices'] as List?)?.map((e) => e as int).toList() 13 | ..text = json['text'] as String?; 14 | } 15 | 16 | Map _$SymbolToJson(Symbol instance) => { 17 | 'indices': instance.indices, 18 | 'text': instance.text, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/api/common/data/hashtag.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'hashtag.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Hashtag _$HashtagFromJson(Map json) { 10 | return Hashtag() 11 | ..indices = 12 | (json['indices'] as List?)?.map((e) => e as int).toList() 13 | ..text = json['text'] as String?; 14 | } 15 | 16 | Map _$HashtagToJson(Hashtag instance) => { 17 | 'indices': instance.indices, 18 | 'text': instance.text, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/api/users/data/derived.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'derived.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Derived _$DerivedFromJson(Map json) { 10 | return Derived() 11 | ..locations = (json['locations'] as List?) 12 | ?.map((e) => Location.fromJson(e as Map)) 13 | .toList(); 14 | } 15 | 16 | Map _$DerivedToJson(Derived instance) => { 17 | 'locations': instance.locations?.map((e) => e.toJson()).toList(), 18 | }; 19 | -------------------------------------------------------------------------------- /lib/api/geo/data/coordinates.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'coordinates.g.dart'; 4 | 5 | @JsonSerializable( 6 | explicitToJson: true, 7 | fieldRename: FieldRename.snake, 8 | ) 9 | class Coordinates { 10 | Coordinates(); 11 | 12 | factory Coordinates.fromJson(Map json) => 13 | _$CoordinatesFromJson(json); 14 | 15 | /// The longitude and latitude of the Tweet’s location, as a collection in the 16 | /// form `[longitude, latitude]`. 17 | List? coordinates; 18 | 19 | /// The type of data encoded in the coordinates property. This will be “Point” 20 | /// for Tweet coordinates fields. 21 | String? type; 22 | 23 | Map toJson() => _$CoordinatesToJson(this); 24 | } 25 | -------------------------------------------------------------------------------- /lib/api/geo/data/coordinates.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'coordinates.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Coordinates _$CoordinatesFromJson(Map json) { 10 | return Coordinates() 11 | ..coordinates = (json['coordinates'] as List?) 12 | ?.map((e) => (e as num).toDouble()) 13 | .toList() 14 | ..type = json['type'] as String?; 15 | } 16 | 17 | Map _$CoordinatesToJson(Coordinates instance) => 18 | { 19 | 'coordinates': instance.coordinates, 20 | 'type': instance.type, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/api/media/data/size.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'size.g.dart'; 4 | 5 | @JsonSerializable( 6 | explicitToJson: true, 7 | fieldRename: FieldRename.snake, 8 | ) 9 | class Size { 10 | Size(); 11 | 12 | factory Size.fromJson(Map json) => _$SizeFromJson(json); 13 | 14 | /// Width in pixels of this size. 15 | int? w; 16 | 17 | /// Height in pixels of this size. 18 | int? h; 19 | 20 | /// Resizing method used to obtain this size. A value of `fit` means that the 21 | /// media was resized to fit one dimension, keeping its native aspect ratio. A 22 | /// value of `crop` means that the media was cropped in order to fit a 23 | /// specific resolution. 24 | String? resize; 25 | 26 | Map toJson() => _$SizeToJson(this); 27 | } 28 | -------------------------------------------------------------------------------- /lib/api/trends/data/trends.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_twitter_api/api/trends/data/trend.dart'; 2 | import 'package:dart_twitter_api/api/trends/data/trend_location.dart'; 3 | import 'package:dart_twitter_api/src/utils/date_utils.dart'; 4 | import 'package:json_annotation/json_annotation.dart'; 5 | 6 | part 'trends.g.dart'; 7 | 8 | @JsonSerializable( 9 | explicitToJson: true, 10 | fieldRename: FieldRename.snake, 11 | ) 12 | class Trends { 13 | Trends(); 14 | 15 | factory Trends.fromJson(Map json) => _$TrendsFromJson(json); 16 | 17 | List? trends; 18 | 19 | @JsonKey(fromJson: convertTwitterDateTime) 20 | DateTime? asOf; 21 | 22 | @JsonKey(fromJson: convertTwitterDateTime) 23 | DateTime? createdAt; 24 | 25 | List? locations; 26 | 27 | Map toJson() => _$TrendsToJson(this); 28 | } 29 | -------------------------------------------------------------------------------- /lib/api/abstract_twitter_client.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dart_twitter_api/twitter_api.dart'; 4 | import 'package:http/http.dart'; 5 | 6 | /// An abstraction to make http calls to the Twitter API used by the 7 | /// services. 8 | /// 9 | /// Implemented by [TwitterClient]. 10 | abstract class AbstractTwitterClient { 11 | const AbstractTwitterClient(); 12 | 13 | Future get( 14 | Uri uri, { 15 | Map? headers, 16 | Duration? timeout, 17 | }); 18 | 19 | Future post( 20 | Uri uri, { 21 | Map? headers, 22 | dynamic body, 23 | Encoding? encoding, 24 | Duration? timeout, 25 | }); 26 | 27 | Future multipartRequest( 28 | Uri uri, { 29 | List? files, 30 | Map? headers, 31 | Duration? timeout, 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /lib/api/common/data/poll.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_twitter_api/api/common/data/option.dart'; 2 | import 'package:dart_twitter_api/src/utils/date_utils.dart'; 3 | import 'package:json_annotation/json_annotation.dart'; 4 | 5 | part 'poll.g.dart'; 6 | 7 | @JsonSerializable( 8 | explicitToJson: true, 9 | fieldRename: FieldRename.snake, 10 | ) 11 | class Poll { 12 | Poll(); 13 | 14 | factory Poll.fromJson(Map json) => _$PollFromJson(json); 15 | 16 | /// An array of options, each having a poll position, and the text for that 17 | /// position. 18 | List