ertgrulll / advstory

An advanced, complete story viewer for Flutter. Has support for images, videos, custom widget contents, gestures, interceptors, listeners, manipulators and much more.
https://advstory.sourcekod.com
MIT License
41 stars 33 forks source link

WidgetStory AnimationController exception #5

Closed jtkeyva closed 2 years ago

jtkeyva commented 2 years ago

Is your feature request related to a problem? Please describe. There is no problem, only opportunity. The widget type is limitless which is great, but what if you want different widget types for say "Image with text" or "3 image rows" or "Video with scrolling text" or "Video with image overlay"?

Describe the solution you'd like Allow devs to define custom content types with templates. Could be as simple as placing dart files within a content_type or content_template folder: image_with_text.dart, three_image_rows.dart, video_with_scrolling_text.dart or video_with_image_overlay.dart

The syntax in the template file could look something like: ContentTypeVideoWithScrollingText or ContentType.videoWithScrollingText or SlideTemplateVideoWithScrollingText or SlideTemplate.videoWithScrollingText

Then in the "cluster" json that populates the stories, you could simply specify what content type / content template will be used for each individual slide. ex ImageWithTextSlide, VideoWithScrollingTextSlide, MyCustomTemplateSlide or ContentType.myCustomTemplate or Slide.myNewSlideTemplate along with your built in ImageSlide VideoSlide WidgetContent.

`ContentType: 'VideoWithScrollingText' {
videoUrl: 'https://mysite.com/linktovideo.mp4'
scrollingText: 'this is the text i want to scroll'
}
`

or

`SlideType: 'ImageWithText' {
videoUrl: 'https://mysite.com/linktovideo.mp4'
scrollingText: 'this is the text i want to scroll'
}
`

or

`Template: 'Advertisement' {
videoUrl: 'https://mysite.com/linktovideo.mp4'
Text: 'Order Now!'
link: 'https://mylink.com/ordernow'
backgroundImageUrl: 'https://mysite.com/bgimage.png'
}
`

Describe alternatives you've considered Hacking and breaking your code

Additional context Your story player outperforms all other packages I've tried. I appreciate your built in functionality and your opinionated approach as is. I think if you break it up a bit and modularize it a bit, it could become one of the more powerful packages for content display, particularly in this full screen story format. Not sure of your goals with this package though.

Not sure how much I can help with code, I'm not an expert. I've never done a PR and still wrapping my head around your code. I can do product development and map things out no problem, but implementing them into your code might be tough.

I can do a $ bounty to get this implemented with the other features if it can become a priority.

jtkeyva commented 2 years ago

Forget everything, you've already done it! The way you built it makes it truly simple to create any "Custom Slide/ContentType Template" you want! Please try to make your own ContentType and battle test it. I think you nailed it!

Probably just a couple tweaks (see end of message) to the way gesture is handled. I can help write documentation on custom ContentTypes and Custom Templates if you want.

Here's the data I customized:

{
      "username": "Virgil T Vogel",
      "profilePicture":
          "https://www.fakepersongenerator.com/Face/male/male1085513896637.jpg",
      "stories": [
        {
          "url":
              "https://images.unsplash.com/photo-1652007682665-e06a8ac589dd?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
          "text": "this is my custom media type!",
          "mediaType": "advertisement",
        },
        {
          "url":
              "https://assets.mixkit.co/videos/preview/mixkit-man-under-multicolored-lights-1237-large.mp4",
          "mediaType": "video",
        },

Here's the customized class:

class Story {
  final String url;
  final String text;
  final MediaType mediaType;

  Story(this.url, this.text, this.mediaType);

  factory Story.fromJson(Map<String, dynamic> map) {
    return Story(
      map['url'] ?? "",
      map['text'] ?? "",
      MediaType.values.firstWhere(
        (element) => element.toString().split(".").last == map['mediaType'],
      ),
    );
  }
}

enum MediaType {
  image,
  video,
  widget,
  advertisement,
}

Here's the template I made:

case MediaType.advertisement:
                return WidgetStory(
                  child: GestureDetector(
                    onVerticalDragStart: (details) => print(details),
                    onTap: () => print('tapped'),
                    child: Container(
                      width: MediaQuery.of(context).size.width,
                      height: MediaQuery.of(context).size.height,
                      padding: const EdgeInsets.symmetric(horizontal: 25),
                      alignment: Alignment.center,
                      color: Colors.red,
                      child: TextButton(
                          onPressed: (() {
                            print('text button tapped');
                          }),
                          child: Text(story.text)),
                    ),
                  ),
                );

Only problem is, when tapping the TextButton it breaks: Exception has occurred. FlutterError (AnimationController.forward() called with no default duration. The "duration" property should be set, either in the constructor or later, before calling the forward() function.)

If this gets fixed, I should be able to drop this in as a replacement to my setup and really start to contribute to your code :)

PS: Naming it ContentType (like Drupal does) might be more universal instead of MediaType since there can be several different types of media within a piece of content.

PPS: Great job again, this really is an awesome package!

jtkeyva commented 2 years ago

Wanted to note there's a foregroundBuilder option in this package: https://pub.dev/packages/wechat_camera_picker

typedef ForegroundBuilder = Widget Function( BuildContext context, CameraValue cameraValue, );

Figure you can use some ideas from there?

ertgrulll commented 2 years ago

Hi, thanks for your feedback. WidgetStory throws an error when first item in story view, I can reproduce issue. I will release a new version today to fix this issue.


Naming it ContentType (like Drupal does) might be more universal instead of MediaType since there can be several different types of media within a piece of content.

MediaType is from example project, i created this enum for generating mock data for showcase, it's not about the package itself. You can use any name inside of your project. Although, I'll rename the enum to avoid confusion.


typedef ForegroundBuilder = Widget Function( BuildContext context, CameraValue cameraValue, );

How will it be useful in this package? You can use WidgetStory if it's about using custom widgets over the image or video media. I will add a way to use cached media inside WidgetStory in next releases, this way you don't have to create your own caching mechanism for custom story types.


I can do a $ bounty to get this implemented with the other features if it can become a priority. PPS: Great job again, this really is an awesome package!

I'm grateful for your all kind of supports, I will add be a sponsor or buy me a coffee button to the readme 🙏🏼

jtkeyva commented 2 years ago

You're welcome. I'm starting to understand how things are working under the hood now :)

Yes, you're right I think it's fine the way you have it, just thought foregroundBuilder was an interesting concept. And yes, I was just thinking about the caching mechanism as part of the WidgetStory slide. That is vital and will unlock a lot of power to create super cool or complex slides.

Not sure how or if you support pre-caching or pre-loading? Would be nice to specify how many pages forward/back to preload. This package seems to work ok: https://pub.dev/packages/preload_page_view

I'll back off with the feature requests/suggesgtions. There's just a couple more nagging at me but I'll wait to see if I can help implement them. I will most certainly buy you a giant coffee! Or perhaps become a sponsor once I get it implemented into my app. Please notify when you get the link up.

Again, really great job on the package and awesome job following up on issues 👍

ertgrulll commented 2 years ago

Bug fixed, added parameters to enable/disable preloading, thanks for your suggestions.