packages/chore/remove_unused #85
10
packages/wyatt_medium_feeds/.gitignore
vendored
10
packages/wyatt_medium_feeds/.gitignore
vendored
@ -1,10 +0,0 @@
|
|||||||
# Files and directories created by pub.
|
|
||||||
.dart_tool/
|
|
||||||
.packages
|
|
||||||
|
|
||||||
# Conventional directory for build outputs.
|
|
||||||
build/
|
|
||||||
|
|
||||||
# Omit committing pubspec.lock for library packages; see
|
|
||||||
# https://dart.dev/guides/libraries/private-files#pubspeclock.
|
|
||||||
pubspec.lock
|
|
@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 WYATT GROUP
|
|
||||||
* Please see the AUTHORS file for details.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"psioniq.psi-header",
|
|
||||||
"blaugold.melos-code"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
{
|
|
||||||
"psi-header.changes-tracking": {
|
|
||||||
"isActive": true
|
|
||||||
},
|
|
||||||
"psi-header.config": {
|
|
||||||
"blankLinesAfter": 1,
|
|
||||||
"forceToTop": true
|
|
||||||
},
|
|
||||||
"psi-header.lang-config": [
|
|
||||||
{
|
|
||||||
"beforeHeader": [
|
|
||||||
"# -*- coding:utf-8 -*-",
|
|
||||||
"#!/usr/bin/env python3"
|
|
||||||
],
|
|
||||||
"begin": "###",
|
|
||||||
"end": "###",
|
|
||||||
"language": "python",
|
|
||||||
"prefix": "# "
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"beforeHeader": [
|
|
||||||
"#!/usr/bin/env sh",
|
|
||||||
""
|
|
||||||
],
|
|
||||||
"language": "shellscript",
|
|
||||||
"begin": "",
|
|
||||||
"end": "",
|
|
||||||
"prefix": "# "
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"begin": "",
|
|
||||||
"end": "",
|
|
||||||
"language": "dart",
|
|
||||||
"prefix": "// "
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"begin": "",
|
|
||||||
"end": "",
|
|
||||||
"language": "yaml",
|
|
||||||
"prefix": "# "
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"begin": "<!--",
|
|
||||||
"end": "-->",
|
|
||||||
"language": "markdown",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"psi-header.templates": [
|
|
||||||
{
|
|
||||||
"language": "*",
|
|
||||||
"template": [
|
|
||||||
"Copyright (C) <<year>> WYATT GROUP",
|
|
||||||
"Please see the AUTHORS file for details.",
|
|
||||||
"",
|
|
||||||
"This program is free software: you can redistribute it and/or modify",
|
|
||||||
"it under the terms of the GNU General Public License as published by",
|
|
||||||
"the Free Software Foundation, either version 3 of the License, or",
|
|
||||||
"any later version.",
|
|
||||||
"",
|
|
||||||
"This program is distributed in the hope that it will be useful,",
|
|
||||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of",
|
|
||||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
|
|
||||||
"GNU General Public License for more details.",
|
|
||||||
"",
|
|
||||||
"You should have received a copy of the GNU General Public License",
|
|
||||||
"along with this program. If not, see <https://www.gnu.org/licenses/>."
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"dart.runPubGetOnPubspecChanges": false,
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
## 1.0.1
|
|
||||||
|
|
||||||
- **FIX**: remove useless example file.
|
|
||||||
|
|
||||||
## 1.0.0
|
|
||||||
|
|
||||||
- Initial version.
|
|
@ -1,39 +0,0 @@
|
|||||||
<!--
|
|
||||||
This README describes the package. If you publish this package to pub.dev,
|
|
||||||
this README's contents appear on the landing page for your package.
|
|
||||||
|
|
||||||
For information about how to write a good package README, see the guide for
|
|
||||||
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
|
|
||||||
|
|
||||||
For general information about developing packages, see the Dart guide for
|
|
||||||
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
|
|
||||||
and the Flutter guide for
|
|
||||||
[developing packages and plugins](https://flutter.dev/developing-packages).
|
|
||||||
-->
|
|
||||||
|
|
||||||
TODO: Put a short description of the package here that helps potential users
|
|
||||||
know whether this package might be useful for them.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
TODO: List prerequisites and provide or point to information on how to
|
|
||||||
start using the package.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
TODO: Include short and useful examples for package users. Add longer examples
|
|
||||||
to `/example` folder.
|
|
||||||
|
|
||||||
```dart
|
|
||||||
const like = 'sample';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Additional information
|
|
||||||
|
|
||||||
TODO: Tell users more about the package: where to find more information, how to
|
|
||||||
contribute to the package, how to file issues, what response they can expect
|
|
||||||
from the package authors, and more.
|
|
@ -1 +0,0 @@
|
|||||||
include: package:wyatt_analysis/analysis_options.flutter.yaml
|
|
46
packages/wyatt_medium_feeds/example/.gitignore
vendored
46
packages/wyatt_medium_feeds/example/.gitignore
vendored
@ -1,46 +0,0 @@
|
|||||||
# Miscellaneous
|
|
||||||
*.class
|
|
||||||
*.log
|
|
||||||
*.pyc
|
|
||||||
*.swp
|
|
||||||
.DS_Store
|
|
||||||
.atom/
|
|
||||||
.buildlog/
|
|
||||||
.history
|
|
||||||
.svn/
|
|
||||||
|
|
||||||
# IntelliJ related
|
|
||||||
*.iml
|
|
||||||
*.ipr
|
|
||||||
*.iws
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
# The .vscode folder contains launch configuration and tasks you configure in
|
|
||||||
# VS Code which you may wish to be included in version control, so this line
|
|
||||||
# is commented out by default.
|
|
||||||
#.vscode/
|
|
||||||
|
|
||||||
# Flutter/Dart/Pub related
|
|
||||||
**/doc/api/
|
|
||||||
**/ios/Flutter/.last_build_id
|
|
||||||
.dart_tool/
|
|
||||||
.flutter-plugins
|
|
||||||
.flutter-plugins-dependencies
|
|
||||||
.packages
|
|
||||||
.pub-cache/
|
|
||||||
.pub/
|
|
||||||
/build/
|
|
||||||
|
|
||||||
# Web related
|
|
||||||
lib/generated_plugin_registrant.dart
|
|
||||||
|
|
||||||
# Symbolication related
|
|
||||||
app.*.symbols
|
|
||||||
|
|
||||||
# Obfuscation related
|
|
||||||
app.*.map.json
|
|
||||||
|
|
||||||
# Android Studio will place build artifacts here
|
|
||||||
/android/app/debug
|
|
||||||
/android/app/profile
|
|
||||||
/android/app/release
|
|
@ -1,10 +0,0 @@
|
|||||||
# This file tracks properties of this Flutter project.
|
|
||||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
|
||||||
#
|
|
||||||
# This file should be version controlled and should not be manually edited.
|
|
||||||
|
|
||||||
version:
|
|
||||||
revision: 5464c5bac742001448fe4fc0597be939379f88ea
|
|
||||||
channel: stable
|
|
||||||
|
|
||||||
project_type: app
|
|
@ -1,16 +0,0 @@
|
|||||||
# medium_feeds_example
|
|
||||||
|
|
||||||
A new Flutter project.
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
|
||||||
|
|
||||||
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
|
|
||||||
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
|
|
||||||
|
|
||||||
For help getting started with Flutter, view our
|
|
||||||
[online documentation](https://flutter.dev/docs), which offers tutorials,
|
|
||||||
samples, guidance on mobile development, and a full API reference.
|
|
@ -1,29 +0,0 @@
|
|||||||
# This file configures the analyzer, which statically analyzes Dart code to
|
|
||||||
# check for errors, warnings, and lints.
|
|
||||||
#
|
|
||||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
|
||||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
|
||||||
# invoked from the command line by running `flutter analyze`.
|
|
||||||
|
|
||||||
# The following line activates a set of recommended lints for Flutter apps,
|
|
||||||
# packages, and plugins designed to encourage good coding practices.
|
|
||||||
include: package:flutter_lints/flutter.yaml
|
|
||||||
|
|
||||||
linter:
|
|
||||||
# The lint rules applied to this project can be customized in the
|
|
||||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
|
||||||
# included above or to enable additional rules. A list of all available lints
|
|
||||||
# and their documentation is published at
|
|
||||||
# https://dart-lang.github.io/linter/lints/index.html.
|
|
||||||
#
|
|
||||||
# Instead of disabling a lint rule for the entire project in the
|
|
||||||
# section below, it can also be suppressed for a single line of code
|
|
||||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
|
||||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
|
||||||
# producing the lint.
|
|
||||||
rules:
|
|
||||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
|
||||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
|
||||||
|
|
||||||
# Additional information about this file can be found at
|
|
||||||
# https://dart.dev/guides/language/analysis-options
|
|
@ -1,76 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class ArticleTile extends StatelessWidget {
|
|
||||||
const ArticleTile({
|
|
||||||
Key? key,
|
|
||||||
required this.bannerUrl,
|
|
||||||
required this.title,
|
|
||||||
required this.summary,
|
|
||||||
required this.author,
|
|
||||||
required this.publishDate,
|
|
||||||
required this.readingTime,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
final String bannerUrl;
|
|
||||||
final String title;
|
|
||||||
final String summary;
|
|
||||||
final String author;
|
|
||||||
final String publishDate;
|
|
||||||
final String readingTime;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
height: 200,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
image: DecorationImage(
|
|
||||||
image: NetworkImage(bannerUrl),
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: Theme.of(context).textTheme.headline6,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
summary,
|
|
||||||
style: Theme.of(context).textTheme.bodyText1,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
author,
|
|
||||||
style: Theme.of(context).textTheme.caption,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Text(
|
|
||||||
publishDate,
|
|
||||||
style: Theme.of(context).textTheme.caption,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Text(
|
|
||||||
readingTime,
|
|
||||||
style: Theme.of(context).textTheme.caption,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:medium_feeds_example/article_tile.dart';
|
|
||||||
import 'package:wyatt_medium_feeds/wyatt_medium_feeds.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
runApp(const MyApp());
|
|
||||||
}
|
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
|
||||||
const MyApp({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
// This widget is the root of your application.
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return MaterialApp(
|
|
||||||
title: 'Flutter Demo',
|
|
||||||
theme: ThemeData(
|
|
||||||
primarySwatch: Colors.blue,
|
|
||||||
),
|
|
||||||
home: const WidgetTree(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ArticleGrid extends StatelessWidget {
|
|
||||||
const ArticleGrid({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final mediumFeed = MediumFeed.fromPublicationName('flutter');
|
|
||||||
return FutureBuilder(
|
|
||||||
future: mediumFeed.parse(),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (snapshot.hasData) {
|
|
||||||
final articles = mediumFeed.articles;
|
|
||||||
return GridView.builder(
|
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: 3,
|
|
||||||
childAspectRatio: 1,
|
|
||||||
),
|
|
||||||
itemCount: articles.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final article = articles[index];
|
|
||||||
return ArticleTile(
|
|
||||||
bannerUrl: article.images.isNotEmpty ? article.images[0] : '',
|
|
||||||
author: article.author,
|
|
||||||
title: article.title,
|
|
||||||
summary: article.summary,
|
|
||||||
readingTime:
|
|
||||||
article.readingTime.inMinutes.toString() + ' min read',
|
|
||||||
publishDate: article.publishDate!.day.toString() +
|
|
||||||
'/' +
|
|
||||||
article.publishDate!.month.toString() +
|
|
||||||
'/' +
|
|
||||||
article.publishDate!.year.toString(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return const Center(child: CircularProgressIndicator());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WidgetTree extends StatelessWidget {
|
|
||||||
const WidgetTree({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: const Text('Medium Feeds Example'),
|
|
||||||
),
|
|
||||||
body: const ArticleGrid(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,93 +0,0 @@
|
|||||||
name: medium_feeds_example
|
|
||||||
description: A new Flutter project.
|
|
||||||
|
|
||||||
# The following line prevents the package from being accidentally published to
|
|
||||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
|
||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|
||||||
|
|
||||||
# The following defines the version and build number for your application.
|
|
||||||
# A version number is three numbers separated by dots, like 1.2.43
|
|
||||||
# followed by an optional build number separated by a +.
|
|
||||||
# Both the version and the builder number may be overridden in flutter
|
|
||||||
# build by specifying --build-name and --build-number, respectively.
|
|
||||||
# In Android, build-name is used as versionName while build-number used as versionCode.
|
|
||||||
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
|
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
|
||||||
# Read more about iOS versioning at
|
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
|
||||||
version: 1.0.0+1
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: ">=2.16.2 <3.0.0"
|
|
||||||
|
|
||||||
# Dependencies specify other packages that your package needs in order to work.
|
|
||||||
# To automatically upgrade your package dependencies to the latest versions
|
|
||||||
# consider running `flutter pub upgrade --major-versions`. Alternatively,
|
|
||||||
# dependencies can be manually updated by changing the version numbers below to
|
|
||||||
# the latest version available on pub.dev. To see which dependencies have newer
|
|
||||||
# versions available, run `flutter pub outdated`.
|
|
||||||
dependencies:
|
|
||||||
flutter:
|
|
||||||
sdk: flutter
|
|
||||||
|
|
||||||
|
|
||||||
wyatt_medium_feeds:
|
|
||||||
path: ../
|
|
||||||
|
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
|
||||||
cupertino_icons: ^1.0.2
|
|
||||||
|
|
||||||
dev_dependencies:
|
|
||||||
flutter_test:
|
|
||||||
sdk: flutter
|
|
||||||
|
|
||||||
# The "flutter_lints" package below contains a set of recommended lints to
|
|
||||||
# encourage good coding practices. The lint set provided by the package is
|
|
||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
|
||||||
# package. See that file for information about deactivating specific lint
|
|
||||||
# rules and activating additional ones.
|
|
||||||
flutter_lints: ^2.0.0
|
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
|
||||||
|
|
||||||
# The following section is specific to Flutter.
|
|
||||||
flutter:
|
|
||||||
|
|
||||||
# The following line ensures that the Material Icons font is
|
|
||||||
# included with your application, so that you can use the icons in
|
|
||||||
# the material Icons class.
|
|
||||||
uses-material-design: true
|
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
|
||||||
# assets:
|
|
||||||
# - images/a_dot_burr.jpeg
|
|
||||||
# - images/a_dot_ham.jpeg
|
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
|
||||||
|
|
||||||
# For details regarding adding assets from package dependencies, see
|
|
||||||
# https://flutter.dev/assets-and-images/#from-packages
|
|
||||||
|
|
||||||
# To add custom fonts to your application, add a fonts section here,
|
|
||||||
# in this "flutter" section. Each entry in this list should have a
|
|
||||||
# "family" key with the font family name, and a "fonts" key with a
|
|
||||||
# list giving the asset and other descriptors for the font. For
|
|
||||||
# example:
|
|
||||||
# fonts:
|
|
||||||
# - family: Schyler
|
|
||||||
# fonts:
|
|
||||||
# - asset: fonts/Schyler-Regular.ttf
|
|
||||||
# - asset: fonts/Schyler-Italic.ttf
|
|
||||||
# style: italic
|
|
||||||
# - family: Trajan Pro
|
|
||||||
# fonts:
|
|
||||||
# - asset: fonts/TrajanPro.ttf
|
|
||||||
# - asset: fonts/TrajanPro_Bold.ttf
|
|
||||||
# weight: 700
|
|
||||||
#
|
|
||||||
# For details regarding fonts from package dependencies,
|
|
||||||
# see https://flutter.dev/custom-fonts/#from-packages
|
|
@ -1,30 +0,0 @@
|
|||||||
// This is a basic Flutter widget test.
|
|
||||||
//
|
|
||||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
|
||||||
// utility that Flutter provides. For example, you can send tap and scroll
|
|
||||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
|
||||||
// tree, read text, and verify that the values of widget properties are correct.
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
import 'package:medium_feeds_example/main.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
|
||||||
// Build our app and trigger a frame.
|
|
||||||
await tester.pumpWidget(const MyApp());
|
|
||||||
|
|
||||||
// Verify that our counter starts at 0.
|
|
||||||
expect(find.text('0'), findsOneWidget);
|
|
||||||
expect(find.text('1'), findsNothing);
|
|
||||||
|
|
||||||
// Tap the '+' icon and trigger a frame.
|
|
||||||
await tester.tap(find.byIcon(Icons.add));
|
|
||||||
await tester.pump();
|
|
||||||
|
|
||||||
// Verify that our counter has incremented.
|
|
||||||
expect(find.text('0'), findsNothing);
|
|
||||||
expect(find.text('1'), findsOneWidget);
|
|
||||||
});
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 917 B |
Binary file not shown.
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
@ -1,104 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<!--
|
|
||||||
If you are serving your web app in a path other than the root, change the
|
|
||||||
href value below to reflect the base path you are serving from.
|
|
||||||
|
|
||||||
The path provided below has to start and end with a slash "/" in order for
|
|
||||||
it to work correctly.
|
|
||||||
|
|
||||||
For more details:
|
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
|
||||||
|
|
||||||
This is a placeholder for base href that will be replaced by the value of
|
|
||||||
the `--base-href` argument provided to `flutter build`.
|
|
||||||
-->
|
|
||||||
<base href="$FLUTTER_BASE_HREF">
|
|
||||||
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
|
||||||
<meta name="description" content="A new Flutter project.">
|
|
||||||
|
|
||||||
<!-- iOS meta tags & icons -->
|
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
|
||||||
<meta name="apple-mobile-web-app-title" content="medium_feeds_example">
|
|
||||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
|
||||||
|
|
||||||
<!-- Favicon -->
|
|
||||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
|
||||||
|
|
||||||
<title>medium_feeds_example</title>
|
|
||||||
<link rel="manifest" href="manifest.json">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- This script installs service_worker.js to provide PWA functionality to
|
|
||||||
application. For more information, see:
|
|
||||||
https://developers.google.com/web/fundamentals/primers/service-workers -->
|
|
||||||
<script>
|
|
||||||
var serviceWorkerVersion = null;
|
|
||||||
var scriptLoaded = false;
|
|
||||||
function loadMainDartJs() {
|
|
||||||
if (scriptLoaded) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
scriptLoaded = true;
|
|
||||||
var scriptTag = document.createElement('script');
|
|
||||||
scriptTag.src = 'main.dart.js';
|
|
||||||
scriptTag.type = 'application/javascript';
|
|
||||||
document.body.append(scriptTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
// Service workers are supported. Use them.
|
|
||||||
window.addEventListener('load', function () {
|
|
||||||
// Wait for registration to finish before dropping the <script> tag.
|
|
||||||
// Otherwise, the browser will load the script multiple times,
|
|
||||||
// potentially different versions.
|
|
||||||
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
|
|
||||||
navigator.serviceWorker.register(serviceWorkerUrl)
|
|
||||||
.then((reg) => {
|
|
||||||
function waitForActivation(serviceWorker) {
|
|
||||||
serviceWorker.addEventListener('statechange', () => {
|
|
||||||
if (serviceWorker.state == 'activated') {
|
|
||||||
console.log('Installed new service worker.');
|
|
||||||
loadMainDartJs();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!reg.active && (reg.installing || reg.waiting)) {
|
|
||||||
// No active web worker and we have installed or are installing
|
|
||||||
// one for the first time. Simply wait for it to activate.
|
|
||||||
waitForActivation(reg.installing || reg.waiting);
|
|
||||||
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
|
|
||||||
// When the app updates the serviceWorkerVersion changes, so we
|
|
||||||
// need to ask the service worker to update.
|
|
||||||
console.log('New service worker available.');
|
|
||||||
reg.update();
|
|
||||||
waitForActivation(reg.installing);
|
|
||||||
} else {
|
|
||||||
// Existing service worker is still good.
|
|
||||||
console.log('Loading app from service worker.');
|
|
||||||
loadMainDartJs();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If service worker doesn't succeed in a reasonable amount of time,
|
|
||||||
// fallback to plaint <script> tag.
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!scriptLoaded) {
|
|
||||||
console.warn(
|
|
||||||
'Failed to load app from service worker. Falling back to plain <script> tag.',
|
|
||||||
);
|
|
||||||
loadMainDartJs();
|
|
||||||
}
|
|
||||||
}, 4000);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Service workers not supported. Just drop the <script> tag.
|
|
||||||
loadMainDartJs();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "medium_feeds_example",
|
|
||||||
"short_name": "medium_feeds_example",
|
|
||||||
"start_url": ".",
|
|
||||||
"display": "standalone",
|
|
||||||
"background_color": "#0175C2",
|
|
||||||
"theme_color": "#0175C2",
|
|
||||||
"description": "A new Flutter project.",
|
|
||||||
"orientation": "portrait-primary",
|
|
||||||
"prefer_related_applications": false,
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "icons/Icon-192.png",
|
|
||||||
"sizes": "192x192",
|
|
||||||
"type": "image/png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "icons/Icon-512.png",
|
|
||||||
"sizes": "512x512",
|
|
||||||
"type": "image/png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "icons/Icon-maskable-192.png",
|
|
||||||
"sizes": "192x192",
|
|
||||||
"type": "image/png",
|
|
||||||
"purpose": "maskable"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "icons/Icon-maskable-512.png",
|
|
||||||
"sizes": "512x512",
|
|
||||||
"type": "image/png",
|
|
||||||
"purpose": "maskable"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'package:html/parser.dart';
|
|
||||||
import 'package:webfeed/webfeed.dart';
|
|
||||||
import 'package:wyatt_medium_feeds/src/reading_time.dart';
|
|
||||||
|
|
||||||
class MediumArticle {
|
|
||||||
final RssItem? _item;
|
|
||||||
|
|
||||||
RssItem get item {
|
|
||||||
if (_item == null) {
|
|
||||||
throw StateError('Feed has not been parsed yet.');
|
|
||||||
}
|
|
||||||
return _item!;
|
|
||||||
}
|
|
||||||
|
|
||||||
MediumArticle(this._item);
|
|
||||||
|
|
||||||
String get title => item.title ?? '';
|
|
||||||
|
|
||||||
String get link => item.link ?? '';
|
|
||||||
|
|
||||||
String get guid => item.guid ?? '';
|
|
||||||
|
|
||||||
String get author => item.dc?.creator ?? '';
|
|
||||||
|
|
||||||
DateTime? get publishDate => item.pubDate;
|
|
||||||
|
|
||||||
String get content => item.content?.value ?? '';
|
|
||||||
|
|
||||||
List<String> get images {
|
|
||||||
final images = <String>[];
|
|
||||||
for (final i in item.content?.images ?? <String>[]) {
|
|
||||||
images.add(i);
|
|
||||||
}
|
|
||||||
return images;
|
|
||||||
}
|
|
||||||
|
|
||||||
String get decoded {
|
|
||||||
final document = parse(content);
|
|
||||||
return document.firstChild?.text ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
String get summary {
|
|
||||||
final regex = RegExp(r'^.*?[\.!\?](?:\s|$)');
|
|
||||||
final match = regex.firstMatch(decoded);
|
|
||||||
return match?.group(0) ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration get readingTime {
|
|
||||||
return decoded.readingTime();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:webfeed/webfeed.dart';
|
|
||||||
import 'package:wyatt_medium_feeds/src/medium_article.dart';
|
|
||||||
|
|
||||||
class MediumFeed {
|
|
||||||
final String? username;
|
|
||||||
final bool mediumSubdomain;
|
|
||||||
final String? publicationName;
|
|
||||||
final String? customDomain;
|
|
||||||
final String? tagName;
|
|
||||||
final String? topicName;
|
|
||||||
|
|
||||||
final String url;
|
|
||||||
|
|
||||||
RssFeed? _feed;
|
|
||||||
|
|
||||||
RssFeed get feed {
|
|
||||||
if (_feed == null) {
|
|
||||||
throw StateError('Feed has not been parsed yet.');
|
|
||||||
}
|
|
||||||
return _feed!;
|
|
||||||
}
|
|
||||||
|
|
||||||
String get title => feed.title ?? '';
|
|
||||||
|
|
||||||
String get description => feed.description ?? '';
|
|
||||||
|
|
||||||
String get image => feed.image?.url ?? '';
|
|
||||||
|
|
||||||
List<MediumArticle> get articles {
|
|
||||||
final articles = <MediumArticle>[];
|
|
||||||
for (final i in feed.items ?? <RssItem>[]) {
|
|
||||||
articles.add(MediumArticle(i));
|
|
||||||
}
|
|
||||||
return articles;
|
|
||||||
}
|
|
||||||
|
|
||||||
MediumFeed.fromUsername(
|
|
||||||
this.username, {
|
|
||||||
bool subdomain = false,
|
|
||||||
String proxy = 'https://cros-anywhere.herokuapp.com/',
|
|
||||||
}) : mediumSubdomain = subdomain,
|
|
||||||
publicationName = null,
|
|
||||||
customDomain = null,
|
|
||||||
tagName = null,
|
|
||||||
topicName = null,
|
|
||||||
url = subdomain
|
|
||||||
? '${proxy}https://$username.medium.com/feed'
|
|
||||||
: '${proxy}https://medium.com/feed/@$username';
|
|
||||||
|
|
||||||
MediumFeed.fromPublicationName(
|
|
||||||
this.publicationName, {
|
|
||||||
String proxy = 'https://cros-anywhere.herokuapp.com/',
|
|
||||||
}) : username = null,
|
|
||||||
mediumSubdomain = false,
|
|
||||||
customDomain = null,
|
|
||||||
tagName = null,
|
|
||||||
topicName = null,
|
|
||||||
url = '${proxy}https://medium.com/feed/$publicationName';
|
|
||||||
|
|
||||||
MediumFeed.fromCustomDomain(
|
|
||||||
this.customDomain, {
|
|
||||||
String proxy = 'https://cros-anywhere.herokuapp.com/',
|
|
||||||
}) : username = null,
|
|
||||||
mediumSubdomain = false,
|
|
||||||
publicationName = null,
|
|
||||||
tagName = null,
|
|
||||||
topicName = null,
|
|
||||||
url = '${proxy}https://$customDomain/feed';
|
|
||||||
|
|
||||||
MediumFeed.fromTagName({
|
|
||||||
this.publicationName,
|
|
||||||
this.tagName,
|
|
||||||
String proxy = 'https://cros-anywhere.herokuapp.com/',
|
|
||||||
}) : username = null,
|
|
||||||
mediumSubdomain = false,
|
|
||||||
customDomain = null,
|
|
||||||
topicName = null,
|
|
||||||
url =
|
|
||||||
'${proxy}https://medium.com/feed/$publicationName/tagged/$tagName';
|
|
||||||
|
|
||||||
MediumFeed.fromTopicName(
|
|
||||||
this.topicName, {
|
|
||||||
String proxy = 'https://cros-anywhere.herokuapp.com/',
|
|
||||||
}) : username = null,
|
|
||||||
mediumSubdomain = false,
|
|
||||||
customDomain = null,
|
|
||||||
publicationName = null,
|
|
||||||
tagName = null,
|
|
||||||
url = '${proxy}https://medium.com/feed/tag/$topicName';
|
|
||||||
|
|
||||||
Future<RssFeed> parse() async {
|
|
||||||
final xmlString = await read(Uri.parse(url));
|
|
||||||
_feed = RssFeed.parse(xmlString);
|
|
||||||
return _feed!;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
extension ReadingTimeX on String {
|
|
||||||
Duration readingTime({
|
|
||||||
int wpm = 200,
|
|
||||||
String suffix = 'min read',
|
|
||||||
String lessMsg = 'less than a minute',
|
|
||||||
}) {
|
|
||||||
bool _ansiWordBound(String c) {
|
|
||||||
return (' ' == c) || ('\n' == c) || ('\r' == c) || ('\t' == c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int words = 0, start = 0, end = length - 1;
|
|
||||||
|
|
||||||
while (_ansiWordBound(this[start])) {
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
while (_ansiWordBound(this[end])) {
|
|
||||||
end--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count real words
|
|
||||||
for (int i = start; i <= end;) {
|
|
||||||
for (; i <= end && !_ansiWordBound(this[i]); i++) {}
|
|
||||||
words++;
|
|
||||||
for (; i <= end && _ansiWordBound(this[i]); i++) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
final minutes = words / wpm;
|
|
||||||
final seconds = (minutes - minutes.floor()) * 60;
|
|
||||||
final Duration duration = Duration(minutes: minutes.floor(), seconds: seconds.floor());
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
// Copyright (C) 2022 WYATT GROUP
|
|
||||||
// Please see the AUTHORS file for details.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
library wyatt_medium_feeds;
|
|
||||||
|
|
||||||
export 'src/medium_article.dart';
|
|
||||||
export 'src/medium_feed.dart';
|
|
||||||
export 'src/reading_time.dart';
|
|
@ -1,19 +0,0 @@
|
|||||||
name: wyatt_medium_feeds
|
|
||||||
description: Medium flux read for Flutter
|
|
||||||
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_medium_feeds
|
|
||||||
version: 1.0.1
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: '>=2.16.2 <3.0.0'
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
http: ^0.13.4
|
|
||||||
webfeed: ^0.7.0
|
|
||||||
html: ^0.15.0
|
|
||||||
|
|
||||||
dev_dependencies:
|
|
||||||
wyatt_analysis:
|
|
||||||
git:
|
|
||||||
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
|
||||||
ref: wyatt_analysis-v2.2.2
|
|
||||||
path: packages/wyatt_analysis
|
|
Loading…
x
Reference in New Issue
Block a user