diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a4aaa..f7e0466 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog +# 2.2.0 +### New +- Recognize individual links and apply desired actions on tap. + +### Breaking +- `recognizer` is now `linkGestureRecognizer` callback +- Removed `url_launcher` dependency + # 2.1.2 ### Chore - Dependency updates diff --git a/README.md b/README.md index cae704d..424cb98 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,13 @@ TypeSet('Hello #World!#'); // Renders 'World!' underlined TypeSet('Hello, `World!`'); // Renders 'World!' in monospace // Hyperlink Text Example -TypeSet('§google.com|https://google.com§'); // Renders 'google.com' as a clickable link +TypeSet('§google.com|https://google.com§', + linkRecognizerBuilder: (linkText, url) => + TapGestureRecognizer() + ..onTap = () { + // your desired action + }, + ); // Renders 'google.com' as a link // Dynamic Font Size Example TypeSet('Hey, *Hello world<30>*'); // Renders 'Hello world' with font size 30 diff --git a/example/.gitignore b/example/.gitignore index 24476c5..6c31954 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -5,9 +5,11 @@ *.swp .DS_Store .atom/ +.build/ .buildlog/ .history .svn/ +.swiftpm/ migrate_working_dir/ # IntelliJ related diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 9625e10..7c56964 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/example/ios/Podfile b/example/ios/Podfile index 88359b2..279576f 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '11.0' +# platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index aa46c74..3710e18 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,29 +1,22 @@ PODS: - Flutter (1.0.0) - - path_provider_foundation (0.0.1): - - Flutter - - FlutterMacOS - url_launcher_ios (0.0.1): - Flutter DEPENDENCIES: - Flutter (from `Flutter`) - - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) EXTERNAL SOURCES: Flutter: :path: Flutter - path_provider_foundation: - :path: ".symlinks/plugins/path_provider_foundation/darwin" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 - path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 - url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe -PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 +PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011 -COCOAPODS: 1.11.3 +COCOAPODS: 1.15.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 6bfbfa3..111792e 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -113,7 +113,6 @@ B6F4CE0C58C796581DF0844C /* Pods-Runner.release.xcconfig */, F3947AF51B8B596DF7892175 /* Pods-Runner.profile.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -156,7 +155,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -343,7 +342,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -359,7 +358,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = FV94K6TFFS; + DEVELOPMENT_TEAM = 8D5Y6FBA43; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -421,7 +420,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -470,7 +469,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -488,7 +487,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = FV94K6TFFS; + DEVELOPMENT_TEAM = 8D5Y6FBA43; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -511,7 +510,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = FV94K6TFFS; + DEVELOPMENT_TEAM = 8D5Y6FBA43; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a6b826d..c53e2b3 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift index 70693e4..b636303 100644 --- a/example/ios/Runner/AppDelegate.swift +++ b/example/ios/Runner/AppDelegate.swift @@ -1,7 +1,7 @@ import UIKit import Flutter -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, diff --git a/example/lib/main.dart b/example/lib/main.dart index 9f83af9..4faffe3 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:flutter/gestures.dart' show TapGestureRecognizer; import 'package:flutter/material.dart'; import 'package:typeset/typeset.dart'; @@ -31,26 +32,26 @@ class TypeSetExample extends StatelessWidget { ), body: Center( child: ListView( - children: const [ + children: [ Padding( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( horizontal: 22, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Divider(), - Text( + const Divider(), + const Text( 'Usage', style: TextStyle( fontSize: 20, ), ), - Divider(), - SizedBox( + const Divider(), + const SizedBox( height: 12, ), - Text( + const Text( ''' Bold → Hello, *World!* @@ -75,96 +76,108 @@ Link ), ), - Divider(), - Text( + const Divider(), + const Text( 'Samples', style: TextStyle( fontSize: 20, ), ), - Divider(), + const Divider(), - SizedBox( + const SizedBox( height: 12, ), TypeSet( '→ *TypeSet* _can_ #style# ~everything~ `you need` §with|https://rohanjsh.dev/§ _dynamic<18>_ _font<28>_ _size<25>_', - style: TextStyle( + style: const TextStyle( fontSize: 18, ), - ), - SizedBox( + linkRecognizerBuilder: (linkText, url) { + return TapGestureRecognizer() + ..onTap = () { + debugPrint('URL: $url and Text: $linkText'); + }; + }, + ), + const SizedBox( height: 24, ), - Divider(), - Text( + const Divider(), + const Text( 'Supported Stylings', style: TextStyle( fontSize: 20, ), ), - Divider(), + const Divider(), - SizedBox( + const SizedBox( height: 12, ), - TypeSet( - 'Bold:\n→ *Bold Text*', + const TypeSet( + 'Bold:\n→ Hello<20> world', style: TextStyle( fontSize: 24, ), ), - SizedBox( + const SizedBox( height: 20, ), - TypeSet( + const TypeSet( 'Italic:\n→ _Italic Text_ ', style: TextStyle( fontSize: 24, ), ), - SizedBox( + const SizedBox( height: 20, ), - TypeSet( + const TypeSet( 'Underline:\n→ #Underline Text#', style: TextStyle( fontSize: 24, ), ), - SizedBox( + const SizedBox( height: 20, ), - TypeSet( + const TypeSet( 'Strikethrough:\n→ ~Strikethrough Text~', style: TextStyle( fontSize: 24, ), ), - SizedBox( + const SizedBox( height: 20, ), - TypeSet( + const TypeSet( 'Monospace:\n→ `monospace text`', style: TextStyle( fontSize: 24, ), ), - SizedBox( + const SizedBox( height: 20, ), //customized link textstyle and recognizer (tap recognizer) TypeSet( 'Link:\n→ §google.com|https://google.com§', - style: TextStyle( + style: const TextStyle( fontSize: 24, ), - ), - SizedBox( + linkRecognizerBuilder: (linkText, url) { + return TapGestureRecognizer() + ..onTap = () { + debugPrint('URL: $url and Text: $linkText'); + }; + }, + ), + const SizedBox( height: 20, ), - Divider(), + const Divider(), ], ), ) diff --git a/lib/src/core/typeset_controller.dart b/lib/src/core/typeset_controller.dart index 4794edc..fcad01f 100644 --- a/lib/src/core/typeset_controller.dart +++ b/lib/src/core/typeset_controller.dart @@ -42,9 +42,9 @@ import 'package:typeset/src/models/style_type_value_model.dart'; /// 9. Return the `list` of `TypeValueModel` objects. /// /// Outputs: -/// - `list` (List): A list of `TypeValueModel` objects -/// representing the manipulated string. Each object contains a style type -/// and the corresponding text segment. +/// - `list` : A list of `StyleTypeValueModel` +/// objects representing the manipulated string. +/// Each object contains a style type and the corresponding text segment. class TypesetController { /// The constructor for the TypesetController class. TypesetController({ diff --git a/lib/src/core/typeset_parser.dart b/lib/src/core/typeset_parser.dart index dc26bfc..7a187b8 100644 --- a/lib/src/core/typeset_parser.dart +++ b/lib/src/core/typeset_parser.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:typeset/src/core/typeset_controller.dart'; import 'package:typeset/src/models/style_type_enum.dart'; import 'package:typeset/typeset.dart'; -import 'package:url_launcher/url_launcher.dart'; ///[TypesetParser] class TypesetParser { @@ -35,8 +34,8 @@ class TypesetParser { /// - [inputText] (required): A string represents the input text to be parsed. /// - [linkStyle] (optional): A [TextStyle] object represents the style /// to be applied to link text. - /// - [recognizer] (optional): A [GestureRecognizer] object representing - /// the tap gesture recognizer for links. + /// - [linkRecognizerBuilder] (optional): A [GestureRecognizer] object + /// representing the tap gesture recognizer for links. /// - [monospaceStyle] (optional): A [TextStyle] object representing /// the style to be applied to monospace text. /// @@ -67,7 +66,7 @@ class TypesetParser { static List parser({ required String inputText, TextStyle? linkStyle, - GestureRecognizer? recognizer, + GestureRecognizer Function(String text, String url)? linkRecognizerBuilder, TextStyle? monospaceStyle, TextStyle? boldStyle, }) { @@ -100,11 +99,7 @@ class TypesetParser { fontSize: fontSize, decorationColor: Colors.blue, ), - recognizer: recognizer ?? - (TapGestureRecognizer() - ..onTap = () => _launchUrl( - url, - )), + recognizer: linkRecognizerBuilder?.call(linkText, url), ), ); break; @@ -156,18 +151,4 @@ class TypesetParser { } return spans; } - - static Future _launchUrl(String url) async { - if (await canLaunchUrl( - Uri.parse( - url, - ), - )) { - await launchUrl( - Uri.parse( - url, - ), - ); - } - } } diff --git a/lib/src/view/typeset.dart b/lib/src/view/typeset.dart index 965fdb5..4143a6d 100644 --- a/lib/src/view/typeset.dart +++ b/lib/src/view/typeset.dart @@ -1,10 +1,10 @@ -/// {@template typeset} -/// WhatsApp like text formatting for you! -/// {@endtemplate} import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; import 'package:typeset/src/core/typeset_parser.dart'; +/// {@template typeset} +/// WhatsApp like text formatting for you! +/// {@endtemplate} /// Format the text with different styles, similar to whatsapp /// /// Following is the usage: @@ -44,7 +44,7 @@ class TypeSet extends StatelessWidget { this.textHeightBehavior, this.selectionColor, this.strutStyle, - this.recognizer, + this.linkRecognizerBuilder, this.linkStyle, this.monospaceStyle, this.boldStyle, @@ -105,8 +105,9 @@ class TypeSet extends StatelessWidget { final StrutStyle? strutStyle; - ///[recognizer] is the recognizer of the text - final GestureRecognizer? recognizer; + ///[linkRecognizerBuilder] is the recognizer of the text + final GestureRecognizer Function(String linkText, String url)? + linkRecognizerBuilder; ///[linkStyle] is the style of the link final TextStyle? linkStyle; @@ -124,7 +125,7 @@ class TypeSet extends StatelessWidget { TextSpan( children: TypesetParser.parser( inputText: inputText, - recognizer: recognizer, + linkRecognizerBuilder: linkRecognizerBuilder, linkStyle: linkStyle, monospaceStyle: monospaceStyle, boldStyle: boldStyle, diff --git a/lib/src/view/typeset_ext.dart b/lib/src/view/typeset_ext.dart index 04d65fe..720fd15 100644 --- a/lib/src/view/typeset_ext.dart +++ b/lib/src/view/typeset_ext.dart @@ -19,7 +19,7 @@ extension TypeSetExtension on String { TextHeightBehavior? textHeightBehavior, Color? selectionColor, StrutStyle? strutStyle, - GestureRecognizer? recognizer, + GestureRecognizer Function(String linkText, String url)? recognizerBuilder, TextStyle? linkStyle, TextStyle? boldStyle, TextStyle? monospaceStyle, @@ -39,7 +39,7 @@ extension TypeSetExtension on String { textHeightBehavior: textHeightBehavior, selectionColor: selectionColor, strutStyle: strutStyle, - recognizer: recognizer, + linkRecognizerBuilder: recognizerBuilder, linkStyle: linkStyle, boldStyle: boldStyle, monospaceStyle: monospaceStyle, diff --git a/pubspec.yaml b/pubspec.yaml index 6f017b6..58e47b1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: typeset description: Whatsapp like text styling for you! -- Bold, Italic, Underline and more -- Drive your text style through Backend! -version: 2.1.2 +version: 2.2.0 repository: https://github.com/rohanjsh/typeset/ screenshots: - description: "Examples of the typeset formatters" @@ -13,7 +13,6 @@ environment: dependencies: flutter: sdk: flutter - url_launcher: ^6.3.0 dev_dependencies: diff --git a/test/src/core/typeset_parser_test.dart b/test/src/core/typeset_parser_test.dart index 0269866..85982da 100644 --- a/test/src/core/typeset_parser_test.dart +++ b/test/src/core/typeset_parser_test.dart @@ -11,7 +11,7 @@ void main() { test('Parser with monospace', testMonoSpaceInParser); test('Parser with custom styling', testCustomStyling); test('Parser with font size', testFontSize); - test('Parser with url launcher', testUrlLauncher); + test('Parser with recognizer', testUrlLauncher); }, ); } @@ -60,7 +60,7 @@ void testCustomStyling() { final spans = TypesetParser.parser( inputText: inputText, linkStyle: linkStyle, - recognizer: recognizer, + linkRecognizerBuilder: (linkText, url) => recognizer, boldStyle: boldStyle, ); @@ -99,6 +99,8 @@ void testUrlLauncher() { const inputText = 'This is a §link|https://google.com§'; final spans = TypesetParser.parser( inputText: inputText, + linkRecognizerBuilder: (text, url) => TapGestureRecognizer() + ..onTap = () => debugPrint('URL: $url and Text: $text'), ); expect(spans[1].recognizer.runtimeType, TapGestureRecognizer); diff --git a/test/src/view/typeset_test.dart b/test/src/view/typeset_test.dart index 47a93ad..597d0bc 100644 --- a/test/src/view/typeset_test.dart +++ b/test/src/view/typeset_test.dart @@ -170,7 +170,13 @@ void main() { test('parses link correctly', () { const inputText = '§Example|http://example.com§'; - final result = TypesetParser.parser(inputText: inputText); + final result = TypesetParser.parser( + inputText: inputText, + linkRecognizerBuilder: (linkText, url) => TapGestureRecognizer() + ..onTap = () { + debugPrint('Link tapped'); + }, + ); expect(result.length, 1); final linkSpan = result[0]; diff --git a/test/src/view/typeset_widget.dart b/test/src/view/typeset_widget.dart index 3a50802..efafe9a 100644 --- a/test/src/view/typeset_widget.dart +++ b/test/src/view/typeset_widget.dart @@ -1,3 +1,4 @@ +import 'package:flutter/gestures.dart' show TapGestureRecognizer; import 'package:flutter/material.dart'; import 'package:typeset/typeset.dart'; @@ -24,6 +25,11 @@ class TypeSetTest extends StatelessWidget { TypeSet( title!, style: style, + linkRecognizerBuilder: (linkText, url) => + TapGestureRecognizer() + ..onTap = () { + debugPrint('Link tapped'); + }, ), if (titleForExt != null) titleForExt!.typeset(