Maintain scroll location to prevent content jumping when network images or dynamic network content loads into a listview that has already been laid out

Consider, if there is a ListView with a number of variable height Widgets with further contain network image's that load at their own pace.
When the images load, the height of each individual listview item widget will change (increase) appropriately
If this set of events occurs above the users current scroll position in the listview, then the content will shift / jump.  The result is that the user is now looking at content that was formerly above their last viewed position.
This gives for bad user experience.
Is it possible to add an option to listviews (or any scrollable view) that the scroll position should maintain itself relative to the bottom extent of the listview when a layout change occurs above the current position or vice versa when it occurs under neath the current position (as it is currently works).  In this way from the user POV, there is not content jumping effect
In the HTML/CSS world this effect has sometimes been called Layout Jank (https://css-tricks.com/the-fight-against-layout-jank/) which has been addressed with various forms of scroll anchoring
(https://blog.chromium.org/2017/04/scroll-anchoring-for-web-developers.html)
(https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor/Guide_to_scroll_anchoring)
https://www.youtube.com/watch?time_continue=15&v=-Fr-i4dicCQ&feature=emb_title
In this case, it would apply to not just a webview but I guess anything that could be controlled by a ScrollContoller?

@mark8044
Thanks for the report. In order to address this properly, can you provide flutter doctor -v, a minimal reproducible code sample that shows the behavior you reported along with actual vs expected result ?

[✓] Flutter (Channel stable, 2.10.3, on macOS 11.6.4 20G417 darwin-x64, locale en-US)
    • Flutter version 2.10.3 at /Users//Desktop/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 7e9793dee1 (5 days ago), 2022-03-02 11:23:12 -0600
    • Engine revision bd539267b4
    • Dart version 2.16.1
    • DevTools version 2.9.2

[✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
    • Android SDK at /Users//Library/Android/sdk
    • Platform android-31, build-tools 32.1.0-rc1
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • CocoaPods version 1.11.2

[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[✓] Android Studio (version 2021.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)

[✓] Connected device (1 available)
    • iPhone 13 (mobile) • • ios • com.apple.CoreSimulator.SimRuntime.iOS-15-2 (simulator)

[✓] HTTP Host Availability
    • All required HTTP hosts are available

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        Text('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales mi vel nisi efficitur, sed sollicitudin orci dictum. Phasellus pellentesque ex et libero accumsan porttitor. Ut at enim ex. Nam ultrices risus massa, et tempor lectus finibus eu. Phasellus varius lorem ante, vitae varius nisi elementum nec. Vestibulum blandit ut metus at ultrices. Fusce rhoncus mi enim, a gravida enim egestas ac. Duis nec consequat lectus. Integer vulputate metus ac neque molestie dignissim. Integer lacinia congue nulla molestie elementum. Nulla quis eleifend tortor. In ac nisi ligula. Proin laoreet, metus in ornare tristique, orci lorem aliquet magna, id finibus nisi libero id erat.\n\n'),
        Text('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales mi vel nisi efficitur, sed sollicitudin orci dictum. Phasellus pellentesque ex et libero accumsan porttitor. Ut at enim ex. Nam ultrices risus massa, et tempor lectus finibus eu. Phasellus varius lorem ante, vitae varius nisi elementum nec. Vestibulum blandit ut metus at ultrices. Fusce rhoncus mi enim, a gravida enim egestas ac. Duis nec consequat lectus. Integer vulputate metus ac neque molestie dignissim. Integer lacinia congue nulla molestie elementum. Nulla quis eleifend tortor. In ac nisi ligula. Proin laoreet, metus in ornare tristique, orci lorem aliquet magna, id finibus nisi libero id erat.\n\n'),

        Image.network('https://repository-images.githubusercontent.com/31792824/fb7e5700-6ccc-11e9-83fe-f602e1e1a9f1'),

        Text('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales mi vel nisi efficitur, sed sollicitudin orci dictum. Phasellus pellentesque ex et libero accumsan porttitor. Ut at enim ex. Nam ultrices risus massa, et tempor lectus finibus eu. Phasellus varius lorem ante, vitae varius nisi elementum nec. Vestibulum blandit ut metus at ultrices. Fusce rhoncus mi enim, a gravida enim egestas ac. Duis nec consequat lectus. Integer vulputate metus ac neque molestie dignissim. Integer lacinia congue nulla molestie elementum. Nulla quis eleifend tortor. In ac nisi ligula. Proin laoreet, metus in ornare tristique, orci lorem aliquet magna, id finibus nisi libero id erat.\n\n'),
        Text('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales mi vel nisi efficitur, sed sollicitudin orci dictum. Phasellus pellentesque ex et libero accumsan porttitor. Ut at enim ex. Nam ultrices risus massa, et tempor lectus finibus eu. Phasellus varius lorem ante, vitae varius nisi elementum nec. Vestibulum blandit ut metus at ultrices. Fusce rhoncus mi enim, a gravida enim egestas ac. Duis nec consequat lectus. Integer vulputate metus ac neque molestie dignissim. Integer lacinia congue nulla molestie elementum. Nulla quis eleifend tortor. In ac nisi ligula. Proin laoreet, metus in ornare tristique, orci lorem aliquet magna, id finibus nisi libero id erat.\n\n'),

      ],
    );
  }
}

Here in this listview, when the lsitview is first shown you see the four blocks of Lorem ipsum text next to each other

When the Network.image loads, then the 3rd&4th paragraphs moves downward (appropriately)

Question here is: Can it be reversed somehow where the 1st&2nd paragraphs actually move upward?
For example, maintain the .extentAfter somehow.
I myself tried to manually adjust the ScrollController.position by doing a ScrollController.jumpTo as soon as the image loads, but unfortunately there is a very slight but minimal glitch perceived by the user as the image pushes down and then the screen jumps down to match its old position

@mark8044
Please check below issues and see if they help.
https://github.com/flutter/flutter/issues/40340
https://github.com/flutter/flutter/issues/63946

@darshankawar Unfortunately those two refer to to different scenarios to this one
#40340 refers to maintaining a scrollview position between states using a PageStorageKey
#63946 refers to scroll position when adding (or removing) listview items
The case I'm describing is a dynamic change in a Container (or otherwise) height which then affects the Listview item height pushing the content to a different location from the current scrollview location, giving an unpleasant experience.
In the HTML/CSS world this effect has sometimes been called Layout Jank (https://css-tricks.com/the-fight-against-layout-jank/) which has been addressed with various forms of scroll anchoring (https://blog.chromium.org/2017/04/scroll-anchoring-for-web-developers.html)
https://www.youtube.com/watch?time_continue=15&v=-Fr-i4dicCQ&feature=emb_title

Thanks for the update.

Question here is: Can it be reversed somehow where the 1st&2nd paragraphs actually move upward?
For example, maintain the .extentAfter somehow.
I myself tried to manually adjust the ScrollController.position by doing a ScrollController.jumpTo as soon as the image loads, but unfortunately there is a very slight but minimal glitch perceived by the user as the image pushes down and then the screen jumps down to match its old position
Maybe a ScrollPhysics could address this case?

I'll keep this issue open and label it for further insights on potential solution to address maintaining scroll location.
/cc @Piinks

I think the scroll position change is inevitable because the content of the list view changes. For example, if we are at a scroll position of 10 pixels down, and a picture 50 pixels tall above loads, the position of 10 is not longer the same location as it was before - you would want it to adjust to 60.
Scroll position is not content aware, so I don't know that it would be possible for the scroll position to accurately and reliably recalculate where the position 'should' be when the content of the list view is dynamically changing. Similarly, the ListView does not know anything about its children, it does not have specific knowledge of various widgets and does not treat them differently based on what they are.
Have you tried this with the ListView.builder constructor? The snippet of code you provided above does not lazily build its children. Using a builder may improve performance since it won't be building those images that are out of view.
You can also try using ListView.itemExtent or ListView.prototypeItem to better control the length of the list and the calculation of the extent.

I think the scroll position change is inevitable because the content of the list view changes. For example, if we are at a scroll position of 10 pixels down, and a picture 50 pixels tall above loads, the position of 10 is not longer the same location as it was before - you would want it to adjust to 60.
Scroll position is not content aware, so I don't know that it would be possible for the scroll position to accurately and reliably recalculate where the position 'should' be when the content of the list view is dynamically changing. Similarly, the ListView does not know anything about its children, it does not have specific knowledge of various widgets and does not treat them differently based on what they are.
Have you tried this with the ListView.builder constructor? The snippet of code you provided above does not lazily build its children. Using a builder may improve performance since it won't be building those images that are out of view.
You can also try using ListView.itemExtent or ListView.prototypeItem to better control the length of the list and the calculation of the extent.

Yes I usually use .builder, I just put that example there to demonstrate the concept for triage reasons, but I think most people understand the issue as you demonstrated.
Regardless of what kind of listview we use, an image will load at the speed the network allows and this kind of jank is inevitable if either flutter or us developers can control these page jumps.
The point here is to try to elevate Flutter.  Tackling this kind of scroll jank sets browsers and websites apart from the rest.
Why not here as well?   So much of Flutter is based around smooth UI, this kind of jank stands out a bit in 2022
If unwilling, how about opening up paths for us to deall with this issue?  Every attempt I've tried to make to compensate the page scroll position based on image load fails because there will always be a 1 frame difference between when the image is presented and when the scrollcontroller jumpTo can be executed, resulting in an every so slight 'glitch' seen on screen as the image loads and position jumps, which is at least equally if not more unappealing as the layout jank or cumulative layout shift or whatever you want to call it.
In terms of UI/UX I would consider this a major issue-- Google's own Core Web Vitals initiative: https://web.dev/cls/
Thank you!

If unwilling, how about opening up paths for us to deall with this issue?

I don't think that anyone is unwilling to resolve this issue, it is currently open. Flutter too is also an open project, and all contributions are welcome from anyone that wishes to do so. If that is something you are interested in, please see our contributing guide.
I just remembered there is a widget of the week video for this exact use case though, I hope it is of some help to your use case: https://youtu.be/pK738Pg9cxc

If unwilling, how about opening up paths for us to deall with this issue?

I don't think that anyone is unwilling to resolve this issue, it is currently open. Flutter too is also an open project, and all contributions are welcome from anyone that wishes to do so. If that is something you are interested in, please see our contributing guide.
I just remembered there is a widget of the week video for this exact use case though, I hope it is of some help to your use case: https://youtu.be/pK738Pg9cxc

I wish I was talented enough to contribute a fix for this, for now all I can contribute is the identification of UI issues and some hope.  That someone has an idea for this issue.  Best general idea could come up with is that ScrollPhysics might tackle this?
TBH, I was able to do a hacky, but pixel perfect, correction for the issue by monitoring the size of the widget for changes.  When the widget changed size, the function would calculate the difference between the old widget size and new widget size and then move the scrollcontroller position down by that many pixels using jumpTo.  The main issue is the timing of that series of events.  In reality, what is happening is that the image loads, pushes content down and then the jumpTo is fired  sequentially rather then simultaneously so there is a frame delay with that.  I ended up throwing it in the trash bin because it is a hack and the frame shift is just as bad as a the core problem in terms of a smooth and professional UI experience.
That FadeInImage widget won't work because the crux of the problem here is that the image size isn't known until after it is retrieved, and really the problem applies to more then just images, any kind of dynamic content change will result in the same effect.  Framing all images in a one size fits all box ahead of time also skirts the issue, but is not a viable solution if you want to display images in their true dimensions.

Has there been any progress on this issue? I am experiencing the same issue, as are many others. It makes the UI of the Flutter app very janky on scrolling up in a ListView.

Not sure if you are interested, but you may be able to address this issue by wrapping the image in a fix size Widget, so when the image loads up, it doesn't expand beyond that size.
If you are looking for different sized images to show up to remove monotonicity, you can fake that kind of behavior using different sized (but fixed size) Widgets in the ListView, and let images load up in those different sized Widgets, irrespective for their own size. Anyway, it won't be a good design to show the full size image.

Not sure if you are interested, but you may be able to address this issue by wrapping the image in a fix size Widget, so when the image loads up, it doesn't expand beyond that size.
If you are looking for different sized images to show up to remove monotonicity, you can fake that kind of behavior using different sized (but fixed size) Widgets in the ListView, and let images load up in those different sized Widgets, irrespective for their own size. Anyway, it won't be a good design to show the full size image.

Not a reasonable solution, that is just a hack to fake it

The same problem happened to me, too

I spent a whole week dealing with this issue. At first, I tried using ScrollPhysics.adjustPositionForNewDimensions and ScrollPosition.jumpTo, but both had obvious stuttering. However, before I was about to give up on my career as a programmer, I came up with a relatively perfect solution inspired by scrollable_positioned_list. The code was a bit more involved, but I can briefly explain the idea:

Use a CustomScrollView that contains three SliverList and set the center.
Use a GlobalKey to wrap each list item.
Detect position changes and change the center SliverList content.
Use the ScrollPosition.correctBy method to correct the list's position.

By the way, with the idea in mind, it should only take a few hours to achieve a perfect effect, except for the problem of some images being reloaded when scrolling quickly. So, half of the time I was dealing with this problem, and I finally found out that this was caused by didChangeDependencies and ScrollAwareImageProvider, which I solved by copying the Image source code.
My time and ability are limited, so I can only briefly mention the solution I came up with. I hope it helps those who need it.

I spent a whole week dealing with this issue. At first, I tried using ScrollPhysics.adjustPositionForNewDimensions, ScrollPosition.jumpTo, ScrollPosition.correctPixels, and RenderSliver.centerOffsetAdjustment but all of them had obvious stuttering or other issues. However, before I was about to give up on my career as a programmer, I came up with a relatively perfect solution inspired by scrollable_positioned_list. The code was a bit more involved, but I can briefly explain the idea:

Use a CustomScrollView that contains three SliverList and set the center.
Use a GlobalKey to wrap each list item.
Detect position changes and change the center SliverList content.
Use the ScrollPosition.correctBy method to correct the list's position.

By the way, with the idea in mind, it should take a day or two to achieve a relatively perfect effect, except for the problem of some images being reloaded when scrolling quickly. So, half of the time I was dealing with this problem, and I finally found out that this was caused by Image.didChangeDependencies and ScrollAwareImageProvider, which I solved by copying the Image source code.
My time and ability are limited, so I can only briefly mention the solution I came up with. I hope it helps those who need it.

This sounds very cool.  I think I understand how you did it from your description.  I tried something very similar using two sliver lists, but ultimately still failed because of how I loaded the data into the  slivers.  The idea of 3 slivers is very intriguing, but I'm not exactly sure what content you are putting in what.
You should turn your idea into a package, it sounds pretty good....!

This sounds very cool. I think I understand how you did it from your description. I tried something very similar using two sliver lists, but ultimately still failed because of how I loaded the data into the slivers. The idea of 3 slivers is very intriguing, but I'm not exactly sure what content you are putting in what.
I ended up making a future builder that loads the images and then gets the image size. Using that and using scrollposition.correctby method I could flawlessly make the correction jumps, even while the user is scrolling. I got caught up because Im not exactly sure if I'm making two image calls (one to get the image, and the other to get the size) and every so often my triggers to make a pixel correction were not correct, because the image was not exactly above the current scroll location (the image comes in as the user is scrolling, or my app is doing an automatic scroll to a position).
So while I got 95% to the solution, it sounds like you have gotten to 100% of the solution? You way sounds better.
You should turn your idea into a package, it sounds pretty good.... and I would love to try it!

Alright, I didn't originally want to make it a package. You know, packages usually require stronger robustness, and I needed to spend more time programming and testing. I spent a week uploading a package before, but not many people liked it, which made me feel a little sad. I copied the code I was using in my own project, and uploaded it to https://github.com/hgraceb/flop_list_view and https://pub.dev/packages/flop_list_view. However, it's worth mentioning that only the basic usage works, and there are still many areas that haven't been handled yet, so you may encounter various problems. I will spend more time later to improve it, it's not an easy thing to do. I think my idea can be expressed more clearly through the code, I hope you will like it.

It looks very cool!
It is missing many of the other things listview.builder has such as controller, shrink-wrap, cache extent, etc... could all the usual listview options be exposed in your implementation?

It looks very cool!
It is missing many of the other things listview.builder has such as controller, shrink-wrap, cache extent, etc... could all the usual listview options be exposed in your implementation?

I'm sorry, but currently there are many options that have not been provided because I am currently working on the issue of unexpected bounces when jumping. Being able to jump to a specific position in the list is more important to me than these options. I am currently working on this issue, so I do not have any extra time to test and provide more options at this time.

In android you can insert items in any direction
the view stays still!!
and you can scroll to new items (if you need)
so somehow they know how to do it

In a similar case, with SingleChildScrollView I tried the implementation.
I tried to make the offset not change with the size change of SingleChildScrollView child.
I did this by making subclass for ScrollPosition and related class.
It may not answer this issue, but it might be of some help.
Below is my program.
I think you can do the same with ListView.
But for ListView there are more considerations.
The ListView calculates the entire scroll extent from the current "cache area" extent.
Therefore, it often happens that the entire scroll extent (not the exact value but the calculated value) changes just by moving the scroll of the UI.  may related #97676
Therefore, for ListView,  I think we cannot take the way that the ScrollPosition subclass adjusts the offset at any time, as in my below implementation of SingleChildScrollView. This is because it is not clear whether the change in extent is due to child content or due to re-computation.
To achieve this with ListView, one possible method is to prepare a callback that is processed at the timing of applyContentDimensions or applyNewDimensions in the ScrollPosition subclass, and the programmer using ListView can adjust the extent within that callback. Let that callback run when you need it, for example, it can be done immediately after loading "Image.network" or after loading additional data with infinite scroll that changes the dimensions of the content.
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late final CustomScrollController scrollController;

  @override
  void initState() {
    super.initState();
    scrollController =
        CustomScrollController(maintainScrollPositionAtExtentChange: true);
    scrollController.isEndScrollAtInitial = true;
  }

  @override
  void dispose() {
    scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: Text(widget.title),
        ),
        body: SingleChildScrollView(
          controller: scrollController,
          child: Column(
            children: [/*  Some widget that changes extent such as Image.network */],
          ),
        ));
  }
}

/// I needed to create the [CustomScrollController] to use [CustomScrollPositionWithSingleContext].
class CustomScrollController extends ScrollController {
  CustomScrollController({
    super.initialScrollOffset,
    super.keepScrollOffset,
    super.debugLabel,
    this.maintainScrollPositionAtExtentChange = false,
    this.isEndScrollAtInitial = false,
  });

  /// [maintainScrollPositionAtExtentChange] be used to maintain
  /// scroll offset when extent changes.
  /// [isEndScrollAtInitial] be used to set an offset to the end of
  /// the scroll range at the initial time. I don't want to use the
  /// jump method because it has to be called inside the
  /// addPostFrameCallback and the scroll movement is drawn on
  /// the screen.
  bool maintainScrollPositionAtExtentChange = false;
  bool isEndScrollAtInitial = false;

  @override
  ScrollPosition createScrollPosition(
    ScrollPhysics physics,
    ScrollContext context,
    ScrollPosition? oldPosition,
  ) {
    return CustomScrollPositionWithSingleContext(
      physics: physics,
      context: context,
      initialPixels: initialScrollOffset,
      keepScrollOffset: keepScrollOffset,
      oldPosition: oldPosition,
      debugLabel: debugLabel,
      maintainScrollPositionAtExtentChange:
          maintainScrollPositionAtExtentChange,
      forceToEndScroll: isEndScrollAtInitial,
    );
  }
}

class CustomScrollPositionWithSingleContext
    extends ScrollPositionWithSingleContext
    implements CustomScrollActivityDelegate {
  CustomScrollPositionWithSingleContext({
    required super.physics,
    required super.context,
    double? initialPixels,
    super.keepScrollOffset,
    super.oldPosition,
    super.debugLabel,
    this.maintainScrollPositionAtExtentChange = false,
    this.forceToEndScroll = false,
  });

  bool _needsToRelayoutAfterApplyContentDimensions = false;
  ScrollMetrics get oldScrollMetrics => _oldScrollMetrics!;
  ScrollMetrics? _oldScrollMetrics;
  bool maintainScrollPositionAtExtentChange = false;
  bool forceToEndScroll = false;

  @override
  bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) {
    _oldScrollMetrics = copyWith();
    bool ret = super.applyContentDimensions(minScrollExtent, maxScrollExtent);

    // This causes the RenderViewport's performLayout to re-layout by returning the result as false.
    if (maintainScrollPositionAtExtentChange &&
        _needsToRelayoutAfterApplyContentDimensions) {
      _needsToRelayoutAfterApplyContentDimensions = false;
      return false;
    }
    return ret;
  }

  @override
  void applyNewDimensions() {
    if (maintainScrollPositionAtExtentChange &&
        _oldScrollMetrics != null &&
        _oldScrollMetrics!.hasContentDimensions &&
        maxScrollExtent != _oldScrollMetrics!.maxScrollExtent) {
      final double correctValue =
          maxScrollExtent - _oldScrollMetrics!.maxScrollExtent;
      if (activity != null && activity! is CustomBallisticScrollActivity) {
        /// While the scroll animation is running,
        /// in other words, while the activity is running,
        /// Every frame the offset is overwritten by the activity.
        /// So we need to override the animation itself that runs
        /// in this activity.
        correctPositionDuringBallisticScrollActivity(correctValue);
      } else {
        correctPixels(pixels + correctValue);
      }
      _needsToRelayoutAfterApplyContentDimensions = true;
    }
    if (forceToEndScroll) {
      correctPixels(maxScrollExtent);
      forceToEndScroll = false;
    }
    super.applyNewDimensions();
  }

  /// Function only to replace [BallisticScrollActivity] with
  /// [CustomBallisticScrollActivity]
  @override
  void goBallistic(double velocity) {
    assert(hasPixels);
    final Simulation? simulation =
        physics.createBallisticSimulation(this, velocity);
    if (simulation != null) {
      beginActivity(CustomBallisticScrollActivity(
        this,
        simulation,
        context.vsync,
        activity?.shouldIgnorePointer ?? true,
      ));
    } else {
      goIdle();
    }
  }

  /// Replaces the current activity's simulation with the corrected value of offset.
  @override
  void goBallisticWithCorrectedPixel(double velocity, double value) {
    assert(hasPixels);
    if (value <= 0) {
      return;
    }
    double correctedPixel = pixels + value;
    final Simulation? simulation = physics.createBallisticSimulation(
        copyWith(pixels: correctedPixel), velocity);

    if (simulation != null) {
      correctPixels(simulation.x(0.0));
      beginActivity(CustomBallisticScrollActivity(
        this,
        simulation,
        context.vsync,
        activity?.shouldIgnorePointer ?? true,
      ));
    } else {
      goIdle();
    }
  }

  void correctPositionDuringBallisticScrollActivity(double pixels) {
    assert(activity! is CustomBallisticScrollActivity);
    (activity as CustomBallisticScrollActivity)
        .applyNewDimentionsWithCorrect(pixels);
  }
}

/// Implemented just to use the [applyNewDimentionsWithCorrect] function
class CustomBallisticScrollActivity extends BallisticScrollActivity {
  CustomBallisticScrollActivity(
    CustomScrollActivityDelegate delegate,
    Simulation simulation,
    TickerProvider vsync,
    bool shouldIgnorePointer,
  )   : changealbeDelegate = delegate,
        super(delegate, simulation, vsync, shouldIgnorePointer);

  CustomScrollActivityDelegate changealbeDelegate;

  void applyNewDimentionsWithCorrect(double value) {
    changealbeDelegate.goBallisticWithCorrectedPixel(velocity, value);
  }
}

/// Implemented just to provide an abstraction for
///  [goBallisticWithCorrectedPixel].
abstract class CustomScrollActivityDelegate extends ScrollActivityDelegate {
  void goBallisticWithCorrectedPixel(double velocity, double pixel);
}

I think you can do the same with ListView. But for ListView there are more considerations. The ListView calculates the entire scroll extent from the current "cache area" extent. Therefore, it often happens that the entire scroll extent (not the exact value but the calculated value) changes just by moving the scroll of the UI. Therefore, for ListView, I think we cannot take the way that the ScrollPosition subclass adjusts the offset at any time, as in my below implementation of SingleChildScrollView. This is because it is not clear whether the change in extent is due to child content or due to re-computation. To achieve this with ListView, one possible method is to prepare a callback that is processed at the timing of applyContentDimensions or applyNewDimensions in the ScrollPosition subclass, and the programmer using ListView can adjust the extent within that callback. Let that callback run when you need it, for example, it can be done immediately after loading "Image.network" or after loading additional data with infinite scroll that changes the dimensions of the content.

I do appreciate the effort but this is really bad. This doesn't happen in Kotlin or React Native.
Does anyone knows how other major projects tackle this?

try cacheExtent 5000
ListView.builder(
  cacheExtent: 5000,
  …
),

I was experiencing the issue that @mark8044 described in the original post and I can confirm that this fix works! It should be noted that the units are in pixels, not items.

I'm experiencing the same issue here, trying to create a twitter like experience.
When we scroll up in a normal ListView.builder, the items previously disposed are building back on top of the list, causing the scrolling to be janky.
What's worse is, if the placeholders (like loaders) of new items are "taller" than the actual loaded content, causing items shrink after loaded, the new items might become out-of-range again, and jumping indefinitely.

@SongRongLee Yes, very bad, hope they can solve it quickly

i have a idea.把其中的内容作为widget即可

still occuring.

Same issue here unfortunately

I also have this issue. Sadly no fix right now except for the cacheExpand: 5000

Same issue here unfortunately

I fixed it in my case, giving each element in my reorderable list view list (they are feature widgets) a fixed height. this seems to have fixed the issue.

@avocadohooman yeah this issue has occured because of dynamic height and content element. When i used Future Builder with ListView, i faced the issue

I've been exploring Flutter recently for rewriting a React Native app, and I've enjoyed it a lot (so much easier to set up, and the dev tools are great compared to RN), but was surprised that this isn't currently implemented. Scroll anchoring is available in RN when maintainVisibleContentPosition is set to true on a ScrollView/FlatList, and it's also the default behavior in most browsers. Having this available in Flutter so that people don't have to do some little hacks themselves would be a wonderful enhancement.

Pretty crazy that this still isnt adressed with a new listview.builder widget. nearly every networked application with scrolling requires paginating above and below as the user scrolls. does this mean infinite scroll is not possible in flutter without jank?

Ive found a solution that works in principle and might be useful for anyone visiting this issue and perhaps could be useful for the flutter team in providing an official widget.
it implements virtual scrolling similar to : https://blog.logrocket.com/virtual-scrolling-core-principles-and-basic-implementation-in-react/
basically there is only ever max N elements in the list, when new elements are added to the front of the list, overflow is popped off the back of the list and vice versa.
it supports dynamically sized items and maintains the view position of the item in the view
ive provided the code here as a working example of the logic in principle, its a mess and im sure there is some unforseen performance issues i havent taken into account.
The core logic is as follows:

the position in px of an element in the view is:  elViewPos = elPositionInList - scrollPosOfController(the top of the view as a pos in the list)
likewise to determine the correct scrollPosition of the controller to position an element at a particular screen position we can scrollPosOfController = elPositionInList - desiredViewPos
so to place an element at a particular desiredPosition all we need to know is where it starts in the list based on the item extents
We find the first visible element in the list in the scrollListener and track its view position as our anchor element (we want to return to this element when we update the list)
We provide items with fixed heights (but they can all be different heights) and ensure that the items dont change their heights on their own
if we do want to update an item in the list, we have to pass an entire new list of items to the list ( i think this is ok because we are only every holding a small amount of items and a rebuild only rebuilds visible items)
in didWidgetUpdate when we receive the new list of items, we locate our anchor item by its id in the new list of items, and track how far in px it is down the list, then we recenter this item to the screen position that it was in before we updated the list

heres an example using randomly sized boxes that are added at the start and end of the list without jittering
excuse the slightly stuttery scrolling, thats its own seperate issue for flutter scrolling jank caused by un-animated scroll position changes from scrollwheels as tracked by https://github.com/flutter/flutter/issues/32120

import 'package:flutter/material.dart';

class TestScreen extends StatelessWidget {
  const TestScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Parent(),
    );
  }
}

class Parent extends StatefulWidget {
  const Parent({super.key});

  @override
  State<Parent> createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  List<ListItem> myItems = [];

  static const maxItems = 20;
  bool autoAddOnScroll = false;

  ListItem _buildRandomHeightItem(int id) {
    double height = Random().nextInt(64) + 64; // min height of 64 max of 128

    return ListItem(
      id: id,
      child: Container(
        color: Colors.primaries[id % Colors.primaries.length],
        height: height,
        child: Center(
          child: Text('Item $id'),
        ),
      ),
      extent: height,
    );
  }

  @override
  void initState() {
    myItems = List.generate(
      maxItems,
      (index) => _buildRandomHeightItem(index),
    );
    super.initState();
  }

  addItemsToStartOfList(int n) {
    List<ListItem> newItems = List.from(myItems);
    int currentStartingId = myItems.isEmpty ? 0 : myItems.first.id;
    newItems.insertAll(
      0,
      List.generate(
        n,
        (index) => _buildRandomHeightItem(currentStartingId - index - 1),
      ).reversed,
    );

    int overflow = newItems.length - maxItems;
    if (overflow > 0) {
      newItems.removeRange(maxItems, maxItems + overflow);
    }
    setState(() {
      myItems = newItems;
    });
  }

  addItemsToEndOfList(int n) {
    List<ListItem> newItems = List.from(myItems);
    int currentEndingId = myItems.isEmpty ? 0 : myItems.last.id;
    newItems.addAll(
      List.generate(
        n,
        (index) => _buildRandomHeightItem(currentEndingId + index + 1),
      ),
    );

    int overflow = newItems.length - maxItems;
    if (overflow > 0) {
      newItems.removeRange(0, overflow);
    }
    setState(() {
      myItems = newItems;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Column(
          children: [
            ElevatedButton(
              onPressed: () {
                addItemsToStartOfList(5);
              },
              child: Text('Add 5 items to start of list'),
            ),
            ElevatedButton(
              onPressed: () {
                addItemsToEndOfList(5);
              },
              child: Text('Add 5 items to end of list'),
            ),
            Row(
              children: [
                Text('Auto add items on scroll'),
                Switch(
                  value: autoAddOnScroll,
                  onChanged: (value) {
                    setState(() {
                      autoAddOnScroll = value;
                    });
                  },
                ),
              ],
            ),
          ],
        ),
        Expanded(
          child: VirtualScrollList(
            items: myItems,
            onHitBottom: autoAddOnScroll
                ? () {
                    addItemsToEndOfList(5);
                  }
                : null,
            onHitTop: autoAddOnScroll
                ? () {
                    addItemsToStartOfList(5);
                  }
                : null,
          ),
        ),
      ],
    );
  }
}

class ListItem {
  final int id;
  final Widget child;
  final double extent;
  ListItem({required this.child, required this.extent, required this.id});
}

class VirtualScrollList extends StatefulWidget {
  final List<ListItem> items;
  final Function? onHitBottom;
  final Function? onHitTop;
  final double boundaryDetectRange;
  const VirtualScrollList({
    super.key,
    required this.items,
    this.onHitBottom,
    this.onHitTop,
    this.boundaryDetectRange = 100,
  });

  @override
  State<VirtualScrollList> createState() => _VirtualScrollListState();
}

class VisibleItemInfo {
  final int id;
  final double extentFromListStart;
  final double screenPosition;
  VisibleItemInfo({
    required this.id,
    required this.extentFromListStart,
    required this.screenPosition,
  });
}

class _VirtualScrollListState extends State<VirtualScrollList> {
  final ScrollController _scrollController = ScrollController();
  VisibleItemInfo? _anchorItem;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_scrollListener);
  }

  @override
  void dispose() {
    _scrollController.removeListener(_scrollListener);
    _scrollController.dispose();
    super.dispose();
  }

  void _scrollListener() {
    // final RenderBox renderBox = context.findRenderObject() as RenderBox;
    // final listViewOffset = renderBox.localToGlobal(Offset.zero);
    final viewportStart = _scrollController.position.pixels;
    // final viewportEnd = viewportStart + renderBox.size.height;

    double currentExtent = 0;
    for (int i = 0; i < widget.items.length; i++) {
      final item = widget.items[i];
      final itemStartExtent = currentExtent;

      if (itemStartExtent > viewportStart) {
        // This item is visible
        final screenPosition = itemStartExtent - viewportStart;
        _anchorItem = VisibleItemInfo(
          id: item.id,
          extentFromListStart: itemStartExtent,
          screenPosition: screenPosition,
        );
        print('Anchor item: ${_anchorItem!.id} at index ${i}');
        print('Screen position: ${_anchorItem!.screenPosition}');
        print('Extent from list start: ${_anchorItem!.extentFromListStart}');
        // print('listview offset ${listViewOffset.dy}');
        break;
      }

      currentExtent += item.extent;
    }
    print("currentExtentToAnchor: $currentExtent");

    if (_anchorItem != null && widget.onHitBottom != null) {
      if (_scrollController.position.pixels >=
          _scrollController.position.maxScrollExtent -
              widget.boundaryDetectRange) {
        widget.onHitBottom!();
      }
    }

    if (_anchorItem != null && widget.onHitTop != null) {
      if (_scrollController.position.pixels <= widget.boundaryDetectRange) {
        widget.onHitTop!();
      }
    }
  }

  void _scrollAnchorItemToItsScreenPosition() {
    if (_anchorItem == null) return;

    // Find the new position of the anchor item in the list (the anchor item has a new index and the total extent has changed)
    double newExtentToAnchor = 0;
    bool foundAnchor = false;
    for (var item in widget.items) {
      if (item.id == _anchorItem!.id) {
        foundAnchor = true;
        break;
      }
      newExtentToAnchor += item.extent;
    }
    print("newExtentToAnchor: $newExtentToAnchor");

    if (!foundAnchor) {
      print('Anchor item not found');
      return;
    }

    // Calculate the new scroll position
    // final RenderBox renderBox = context.findRenderObject() as RenderBox;
    // final listViewOffset = renderBox.localToGlobal(Offset.zero);
    final desiredScreenPosition = _anchorItem!.screenPosition;

    double newScrollPosition = newExtentToAnchor - desiredScreenPosition;

    // Ensure the new scroll position is within bounds
    newScrollPosition = newScrollPosition.clamp(
        0.0, _scrollController.position.maxScrollExtent);

    // Scroll to the new position
    _scrollController.jumpTo(newScrollPosition);

    // // Update the anchor item info
    // _anchorItem = VisibleItemInfo(
    //   id: _anchorItem!.id,
    //   extentFromListStart: newExtentToAnchor,
    //   screenPosition: desiredScreenPosition + listViewOffset.dy,
    // );

    print(
        'Scrolled anchor item ${_anchorItem!.id} to screen position ${_anchorItem!.screenPosition}');
    print("using scrollpos: ${newScrollPosition} extent: ${newExtentToAnchor}");
  }

  @override
  didUpdateWidget(VirtualScrollList oldWidget) {
    double oldExtent = oldWidget.items.fold(
      0.0,
      (previousValue, element) => (previousValue as double) + element.extent,
    );

    double newExtent = widget.items.fold(
      0.0,
      (previousValue, element) => (previousValue as double) + element.extent,
    );

    double extentToAnchor = 0;
    for (var i = 0; i < widget.items.length; i++) {
      if (widget.items[i].id == _anchorItem!.id) {
        break;
      }
      extentToAnchor += widget.items[i].extent;
    }

    print('oldExtent: $oldExtent, newExtent: $newExtent');
    print("newextentToAnchor didupdate: $extentToAnchor");
    _scrollAnchorItemToItsScreenPosition();
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Theme(
        data: Theme.of(context).copyWith(
            scrollbarTheme: ScrollbarThemeData(
          thumbColor: WidgetStateProperty.all(Colors.black),
        )),
        child: ListView.builder(
          physics: BouncingScrollPhysics(),
          itemExtentBuilder: (index, dim) => widget.items[index].extent,
          controller: _scrollController,
          itemCount: widget.items.length,
          itemBuilder: (context, index) {
            return widget.items[index].child;
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _scrollAnchorItemToItsScreenPosition,
        child: Icon(Icons.refresh),
        tooltip: 'Scroll to anchor item',
      ),
    );
  }
}

hopefully flutter team can look into supporting a virtual scrolling widget like this offically

hgraceb's solution appears to be the only correct one i can find. You need to use two slivers, above and below and then reposition where the split happens. The only extra thing is if everything is in the top sliver you actually want to remove the center key and just make that a reversed sliver so that you cant ovderscroll. If you use a center key and place everything in the top sliver, the controller allows you to scroll to scroll position 0, and with everything in the top (negative scroll positions) this mean nothing is displayed on screen.
This solutions is good because it allows dynamically sized items, lazily loaded items, and doesnt require expanding cache-extent. when the slivers settle with the split, you can resize the window and items that change in size wont shift the list around
The calculations about how to maintain the screen position of an item before adjusting the list is relatively straightforward, but there are issues around maintaining ballistic simulations after reversing the list or un-reversing it. you need to pause the simulations using goBallistic(0.0) and adjust the list to reversed or un-reversed and then restart the simulation using the previous velocity but with an inverted sign. so goBallistic(-existingVelocity).
While this solution requires a GlobalKey on every item, actually when we search and measure the items on screen we only care about the few items that are currently on screen. most of the items will be offscreen and un-built due to lazy loading and so their render contexts will be null and can be quickly skipped.
I think flutter should be able to implement this at a framework level but some state needs to be maintained between layouts, an item that is in the current layout needs its viewport position measured, and then in the next layout that item needs to be re-identified by key and it needs to have the centerkey offset or the scroll offset adjusted such that the screen position == the old screen position. if the new layout of items doesnt contain any items from the previous layout of items obviously theres nothing that can be done.
I think this could be done during layout using RenderSliver.centerOffsetAdjustment and for some RenderSliver.centerOffsetAdjustment is hard-coded to 0.0 so unsure what thats about or if im missing something.
if you go ahead and implement this on your own at the parent widget level theres a few things you need to know

You need to override the scrollController and scrollposition class to expose a getter to get the current ballistic velocity, if the current scroll activity is ballistic and has velocity. this is so drag velocities can be maintained after re-layouting the list
you need to use position.correct() or position.correctBy() as it doesnt cancel the current scroll activities and also doesnt notify listeners. theres a warnign about using this as it should only be used during layout, but thats basically what we are doing, hacking around the existing layout
If you want to hard stop at the bottom of the list, you need to change to a single reversed list when the last item becomes visible  and then change back to the sliver split once the bottom item is not visible, because reversed lists have there scroll position set as the distance of the bottom of the viewport from center, and the distance of an item from the center of the viewport is also measured to the bottom of the item rather than the top there are some transformations that need to be done to get screen positions measured as the top of the item to the top of the viewport. likewise maintaining ballistics across this transformation requires flipping the sign before restarting the sim

Im not going to post my code because its also riddled with other workarounds i have for smooth scroling on scrollwheel events as well as application level logic for my application
Also every now and then correctBy() is being called by the internal scrollable layout process and shifting my scroll position by exact integer multiples of 20px for some reason. Not sure why but it happens very rarely and only when using mouse scroll wheel events (which i have converted to animateTo for smooth scrolling) its so rare i dont care right now and so am going to live with it.
oh and also the scroll bar seems to be completely incompatible with this and will require some custom scroll bar implementation to account for all the scroll position corrections happening while the user is interacting with the scrollbar. Im so exhausted after spending so long trying to get this to work similar to the scroll experience in modern chat apps that im just going to disable the scroll bar for now.

Hello everyone!
I've run into the same problem when building my chat application. I wanted the smoothness of Telegram, so the performance and FPS were vital to me.
After spending days and hours,  I got the solution, and it's in package: flutter_list_view
It works perfectly, without any junks. Also, in my opinion it is much easier to set up that building custom scroll view with two/three slivers.

After spending days and hours, I got the solution, and it's in package: flutter_list_view
It works perfectly, without any junks. Also, in my opinion it is much easier to set up that building custom scroll view with two/three slivers.

@haroke4 Hi, I tried the example code for this package, but no position is anchored when the item height changes. Did I do something wrong? Could you share how you use it?
Code sample
https://github.com/robert-luoqing/flutter_list_view/blob/c976d1041ca1e1341a7fc71788b560bc9a426ac9/example/lib/init_jump_keep_position.dart
import 'dart:math';
import 'dart:math' as math;

import 'package:flutter/material.dart';
import 'package:flutter_list_view/flutter_list_view.dart';

class InitJumpKeepPositionPage extends StatefulWidget {
  const InitJumpKeepPositionPage({Key? key}) : super(key: key);

  @override
  State<InitJumpKeepPositionPage> createState() =>
      _InitJumpKeepPositionPageState();
}

class _InitJumpKeepPositionPageState extends State<InitJumpKeepPositionPage> {
  int currentId = 0;

  List<Map<String, String>> data = [];
  final _random = Random();
  FlutterListViewController viewController = FlutterListViewController();
  String htmlLine = "<div>Single line</div>";

  final _itemCount = 100;
  late final List<double> _itemExtents;

  @override
  initState() {
    super.initState();
    for (var i = 0; i < 100; i++) {
      data.add({
        "key": currentId.toString(),
        "display": "<div><b>$i</b></div>" +
            List.filled(2 + _random.nextInt(10), '\n').join(htmlLine)
      });
      currentId++;
    }

    final heightGenerator = math.Random(2147483647);
    _itemExtents = List.generate(_itemCount, (index) {
      return 80.0 + heightGenerator.nextInt(120);
    });
  }

  @override
  dispose() {
    super.dispose();
  }

  void _insertDataAndRestoreSaveScrollPosition() {
    data.insert(0, {
      "key": currentId.toString(),
      "display": List.filled(2 + _random.nextInt(10), '\n').join(htmlLine)
    });
    currentId++;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Jump to the index what you want"),
      ),
      body: Column(
        children: [
          Wrap(spacing: 20, children: [
            ElevatedButton(
                onPressed: _insertDataAndRestoreSaveScrollPosition,
                child: const Text("Insert line at index 0")),
          ]),
          Expanded(
            child: Scrollbar(
              child: FlutterListView(
                key: ObjectKey(data.hashCode),
                controller: viewController,
                delegate: FlutterListViewDelegate(
                  (BuildContext context, int index) => _buildItem(index),
                  childCount: data.length,
                  keepPosition: true,
                  keepPositionOffset: 0,
                  onItemKey: (index) {
                    return data[index]["key"]!;
                  },
                  initIndex: 90,
                  firstItemAlign: FirstItemAlign.end,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildItem(int index) {
    return FutureBuilder(
      future: Future.delayed(
        Duration(milliseconds: 1000 + _itemExtents[index].toInt() * 5),
        () => _itemExtents[index].toDouble(),
      ),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return Card(
            child: SizedBox(
              width: snapshot.data!,
              height: snapshot.data!,
              child: Center(child: Text('Item $index')),
            ),
          );
        }
        return Card(
          child: SizedBox(
            width: 120,
            height: 120,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Flexible(
                  child: SizedBox(
                    width: 10,
                    height: 10,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  ),
                ),
                const Flexible(
                  child: SizedBox(width: 10),
                ),
                Flexible(
                  flex: 10,
                  child: Text('Item $index'),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

Hi @hgraceb! Sorry for the late reply.
In my code, I've set the keepPositionOffset of the FlutterListView to 0.1, and before adding any data to my List, I check if the curr offset (using FlutterListViewController) is less than or equal to 0.1. if so, I jump/animate to offset 0.15 (which is barely visible on UI).
My code is identical to yours except for the if statement before adding an item to the list.
`
// initialize controller
final listViewController = FlutterListViewController();
// UI
Widget _messagesListView() {
return FlutterListView(
/// Fresh messages are always at the bottom!
reverse: true,
  // assign controller
  controller: listViewController,
  physics: const BouncingScrollPhysics(),

  delegate: FlutterListViewDelegate(
    (context, index) => _itemBuilder(context, index),
    childCount: data.length, // your data length
    onItemKey: _onItemKey,
    keepPosition: true,
    keepPositionOffset: 0.1, //
    firstItemAlign: FirstItemAlign.end,
  ),
);

}
// before adding any data to your list
if (listViewController.hasClients && listViewController.offset < 0.1) {
listViewController.jumpTo(0.15);
}
`
I hope helps :3


Resolve Missing Javadocs in Resource Manager SDKs

This issue is a tracking issue for resolving missing Javadocs in resourcemanager SDKs and is being tracked by #25632.
To verify that a library is compatible with the Standard Doclet the following configurations will need to be added into the POM (if the properties section already exists only add the property values):
<properties>
    <codesnippet.skip>false</codesnippet.skip>
    <javadocDoclet></javadocDoclet>
    <javadocDocletOptions></javadocDocletOptions>
</properties>

Additionally, the build should preferably happen on Java 17 to ensure it works with the latest LTS Doclet tooling.
If any code generation classes are missing Javadocs please file an issue.
When you take an SDKs please leave a comment with which SDKs you'll be fixing or verifying.
The following are SDKs that need to be verified or fixed:

[ ] azure-resourcemanager
[x] azure-resourcemanager-advisor
[x] azure-resourcemanager-apimanagement
[x] azure-resourcemanager-appconfiguration
[x] azure-resourcemanager-applicationinsights
[ ] azure-resourcemanager-appplatform
[x] azure-resourcemanager-automation
[x] azure-resourcemanager-azurearcdata
[x] azure-resourcemanager-azurestack
[x] azure-resourcemanager-azurestackhci
[x] azure-resourcemanager-baremetalinfrastructure
[x] azure-resourcemanager-batch
[x] azure-resourcemanager-batchai
[x] azure-resourcemanager-billing
[x] azure-resourcemanager-botservice
[ ] azure-resourcemanager-cdn
[x] azure-resourcemanager-changeanalysis
[x] azure-resourcemanager-commerce
[x] azure-resourcemanager-consumption
[ ] azure-resourcemanager-containerservice
[ ] azure-resourcemanager-cosmos
[x] azure-resourcemanager-costmanagement
[x] azure-resourcemanager-customerinsights
[x] azure-resourcemanager-databox
[x] azure-resourcemanager-databoxedge
[x] azure-resourcemanager-databricks
[x] azure-resourcemanager-datadog
[x] azure-resourcemanager-datalakeanalytics
[x] azure-resourcemanager-datalakestore
[x] azure-resourcemanager-datamigration
[x] azure-resourcemanager-delegatednetwork
[x] azure-resourcemanager-deploymentmanager
[x] azure-resourcemanager-deviceprovisioningservices
[x] azure-resourcemanager-devspaces
[x] azure-resourcemanager-devtestlabs
[ ] azure-resourcemanager-dns
[x] azure-resourcemanager-elastic
[ ] azure-resourcemanager-eventhubs
[x] azure-resourcemanager-extendedlocation
[x] azure-resourcemanager-frontdoor
[x] azure-resourcemanager-hanaonazure
[x] azure-resourcemanager-hdinsight
[x] azure-resourcemanager-healthbot
[x] azure-resourcemanager-healthcareapis
[x] azure-resourcemanager-hybridcompute
[x] azure-resourcemanager-hybridkubernetes
[x] azure-resourcemanager-hybridnetwork
[x] azure-resourcemanager-imagebuilder
[x] azure-resourcemanager-iothub
[ ] azure-resourcemanager-keyvault
[x] azure-resourcemanager-kubernetesconfiguration
[x] azure-resourcemanager-kusto
[x] azure-resourcemanager-labservices
[x] azure-resourcemanager-loganalytics
[x] azure-resourcemanager-logic
[x] azure-resourcemanager-logz
[x] azure-resourcemanager-machinelearningservices
[x] azure-resourcemanager-maintenance
[x] azure-resourcemanager-managedapplications
[x] azure-resourcemanager-maps
[x] azure-resourcemanager-mariadb
[x] azure-resourcemanager-marketplaceordering
[x] azure-resourcemanager-mediaservices
[x] azure-resourcemanager-mixedreality
[ ] azure-resourcemanager-msi
[x] azure-resourcemanager-mysql
[x] azure-resourcemanager-mysqlflexibleserver
[x] azure-resourcemanager-netapp
[x] azure-resourcemanager-operationsmanagement
[x] azure-resourcemanager-peering
[x] azure-resourcemanager-policyinsights
[x] azure-resourcemanager-postgresql
[x] azure-resourcemanager-postgresqlflexibleserver
[x] azure-resourcemanager-powerbidedicated
[ ] azure-resourcemanager-privatedns
[x] azure-resourcemanager-purview
[x] azure-resourcemanager-recoveryservices
[x] azure-resourcemanager-recoveryservicesbackup
[x] azure-resourcemanager-redisenterprise
[x] azure-resourcemanager-relay
[x] azure-resourcemanager-resourcegraph
[x] azure-resourcemanager-resourcehealth
[x] azure-resourcemanager-resourcemover
[ ] azure-resourcemanager-samples
[x] azure-resourcemanager-security
[ ] azure-resourcemanager-servicebus
[x] azure-resourcemanager-servicefabric
[x] azure-resourcemanager-sqlvirtualmachine
[x] azure-resourcemanager-storagecache
[x] azure-resourcemanager-storageimportexport
[x] azure-resourcemanager-storagepool
[x] azure-resourcemanager-streamanalytics
[x] azure-resourcemanager-subscription
[x] azure-resourcemanager-support
[x] azure-resourcemanager-timeseriesinsights
[ ] azure-resourcemanager-trafficmanager
[x] azure-resourcemanager-videoanalyzer
[x] azure-resourcemanager-vmwarecloudsimple

PR for Lite https://github.com/Azure/azure-sdk-for-java/pull/25647

PR for Premium https://github.com/Azure/azure-sdk-for-java/pull/25656

Verified premium with local run of mvn -DskipTests -Dspotbugs.skip=true -Dcheckstyle.skip=true -Drevapi.skip=true clean install with Java 17.


Pass arguments to constructor?

Is there a way to pass arguments to the class constructor on classToPlain or plainToClass`?

no. constructor is never used in such operations.


Refactoring last tag from Link Header

Refactoring code to get lastTag.
Current logic fails when using orderBy
See https://github.com/Azure/acr-cli/pull/72#issuecomment-664201313

Hi @adusumillipraveen , thanks for the PR! 🌷 I left some comments and hope them help.
I also tested it on my local machine and caught some bugs...
If we set the orderby to timedesc, we will find the returned last parameter contains & character, which will be encoded as %26. However, if we take the encoded tag as a parameter of next request, the %26 will be encoded to %2526, which will leads to unexpected result.

@Wwwsylvia Thanks for your quick review , was quite busy last week and had change only today to pick this up. I have addressed most of the comments you have raised . Can you please let me know if its missing any more scenarios ?
Also, I am thinking https://github.com/Azure/acr-cli/pull/73/files#diff-bd8183c84337996183d0bb9280f6e3efR592 is wrong and it needs to be 123%26latest ?Will try to test it on a repo and update my findings here .

@Wwwsylvia  I have tested some more scenarios by merging to https://github.com/Azure/acr-cli/pull/72 and I can see it working fine with '&' while using orderby. Please let me know if u see any issues.

@Wwwsylvia Have you had a chance to look at the latest changes ?

@Wwwsylvia Have you had a chance to look at the latest changes ?

Sorry, been busy these days... Will find a chance to check this and get back to you.

Sorry, been busy these days... Will find a chance to check this and get back to you.

Hey @Wwwsylvia was wondering if you had a chance to look at it ?


Missing Page Thumbnails Panel

Hi
Thank you for this great app, I am also looking for the pages thumbnails panel, any idea where to start or you have planned for the feature.
Thanks
AW

I trying to add this feature as soon as possible. Thanks for your feedback.


create: true seems broken

See the EventLogger demo here: https://tom-select.js.org/examples/events/
Create an item, observe various events fire for the created item.
Click edit on the EventLogger demo above, goto the JS fiddle, create an item in the demo, observe no events fire for the created item :/ I get the same behaviour with the latest TomSelect from npm

Actually, in the NPM version, create:true works, but either of these two examples from the docs do not work:
create: function(input){
	return {value:input,text:input}
}
create: function(input,callback){
	callback({value:input,text:input});
}

I appear to be a moron, didnt see the hidden overflow styles on that event log div in the Fiddle, maybe remove that?


Cant set a button md_bg_color back to primary_color

Description of the Bug
When you create a MDRaisedButton with a different color than theme_cls.primary_color, you can't set it back to the primary_color. The issue is caused by the following code in kivymd.uix.button:
    def on_md_bg_color(self, instance, value):
        if value != [0.0, 0.0, 0.0, 0.0]:
            self._current_button_color = value

It prevents setting the color to the primary_color.
Code and Logs
from kivy.clock import Clock
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.button import MDRaisedButton
from kivymd.uix.screen import MDScreen

KV = '''
MyScreen
'''

class MyScreen(MDScreen):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.theme_cls = MDApp.get_running_app().theme_cls
        self.button = MDRaisedButton(text='CANCEL')
        self.button.md_bg_color = self.theme_cls.error_color
        self.add_widget(self.button)
        Clock.schedule_once(self.change_button, 10)

    def change_button(self, *_args, **_kwargs):
        self.button.text = "OK"
        self.button.md_bg_color = self.theme_cls.primary_color

class Test(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)

    def build(self):
        return self.screen

    def set_item(self, instance):
        # print(instance.text,"----------this is instance")
        gender = instance.text
        mm = self.root.ids.drop_item.set_item(gender)
        self.root.ids.drop_item.text = gender
        self.smenu.dismiss()

Test().run()

Versions

OS: any
Python: 3.7
Kivy: 1.11.1
KivyMD: master

check the fork in the pull request #501
it's still a work in progress but have a lot of bugfixes for the button's lib and relatives to them, also some improvements

i also had a problem related to button (especially button color)
i had set error_color to a button but when the theme changes the error color changes to the primary_color
Code
from kivymd.app import MDApp
from kivymd.uix.picker import MDThemePicker
from kivy.lang import Builder

kv = """

Screen:
	MDRectangleFlatIconButton:
		text: 'DELETE ROOM'
		icon: 'delete'
		pos_hint: {'center_x': .5, 'center_y': .1}
		text_color: app.theme_cls.error_color
		on_release:
			print('on_release')

	MDIconButton:
		on_release:
			app.pick.open()
"""

class MainsApp(MDApp):
    def build(self):
        self.pick = MDThemePicker()
        return Builder.load_string(kv)

MainsApp().run()

check this #501 .

it's a major upgrade to kivyMD but it's not complete yet.
some bugs shown up

i also had a problem related to button (especially button color)
i had set error_color to a button but when the theme changes the error color changes to the primary_color
Code
from kivymd.app import MDApp
from kivymd.uix.picker import MDThemePicker
from kivy.lang import Builder

kv = """

Screen:
	MDRectangleFlatIconButton:
		text: 'DELETE ROOM'
		icon: 'delete'
		pos_hint: {'center_x': .5, 'center_y': .1}
		text_color: app.theme_cls.error_color
		on_release:
			print('on_release')

	MDIconButton:
		on_release:
			app.pick.open()
"""

class MainsApp(MDApp):
    def build(self):
        self.pick = MDThemePicker()
        return Builder.load_string(kv)

MainsApp().run()

take in count that you're not assigning the error color, but a copy of the error color in theme_cls.
for this in #501 i implemented theme_text_color, to set it to a variety of theme_CLS provided ones.

My use-case is that I want to change color of the button on-the-fly. So the button starts as green for instance, and then turns red. I don't want to change the theme, I want to change the individual button from primary_color to error_color or back.
So like this:
button = MDIconButton(text="CANCEL")
button.md_bg_color = app.theme_cls.error_color
# do something
button.text = "OK"
button.md_mg_color = app.theme_cls.primary_color

This works, except that because of the check in the code, it only works if the button starts with md_bg_color=theme_cls.primary_color and then change it to something else. But if you go the opposite direction, it doesn't work. What am I not understanding why you won't fix that?

My PR solves exactly that

@dolfandringa @podraco is currently making a big update for the "button" module, so let's wait until he finishes his work...

ok cool. I'll just use my personal fork for now and keep that up-to-date with master.

The issue is deprecated due to the new API of the KivyMD library 2.0.0 version


Wireguard interface does not have IPv4 address assigned

Expected Behavior
We hope Calico CNI automatically retries configuring the Wireguard interface IP address in case of failure.
Current Behavior
Unable to recover automatically after failure to configure the Wireguard interface IP address.
So, pods communication is broken between the affected node and other cluster nodes.
On the affected node:
WG interface:
40: wireguard.cali: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default qlen 1000     link/none
node object:
  spec:     bgp:       ipv4Address: <IP_ADDRESS>/24     ipv4VXLANTunnelAddr: <IP_ADDRESS>     orchRefs:     - nodeName: node-3eb2f20d-fbc7-4a92-8948-f2f72ef68ce7       orchestrator: k8s   status:     wireguardPublicKey: TLki4UgTiy04biGtGl690AuMZzLNHO20GntWI9iipl0=
On a healthy node:
WG interface:
40: wireguard.cali: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default qlen 1000     link/none      inet <IP_ADDRESS>/32 scope global wireguard.cali        valid_lft forever preferred_lft forever
node object:
  spec:     bgp:       ipv4Address: <IP_ADDRESS>/24     ipv4VXLANTunnelAddr: <IP_ADDRESS>     orchRefs:     - nodeName: node-48e5cbf4-d2d2-49a9-a407-4cb3fe79559b       orchestrator: k8s     wireguard:       interfaceIPv4Address: <IP_ADDRESS>   status:     wireguardPublicKey: m9TXUUo74FvTEOHtg4w7fYrcBl4SwOweSFuDGkJeIn8=
Possible Solution
N/A
(W/A: restart calico-node pod; IPv4 address on Wireguard interface was allocated after that.)
Steps to Reproduce (for bugs)
The issue was observed once on one node (in a three-node cluster) after a few similar deployment runs (seems to be a rare case). No exact steps found to reproduce it. Wireguard was enabled for Calico before the affected calico-node pod was started. The related calico-node log is attached.
calico-node-log.zip
The possibly related error message:
2023-09-06T20:28:15.696034464Z 2023-09-06 20:28:15.695 [INFO][71] tunnel-ip-allocator/allocateip.go 686: Error updating node node-3eb2f20d-fbc7-4a92-8948-f2f72ef68ce7: %!s(<nil>). Retrying. type="wireguardTunnelAddress"
https://github.com/projectcalico/calico/blob/v3.25.1/node/pkg/allocateip/allocateip.go#L686
Your Environment
Calico version
v3.25.1 (etcd as calico data store, vxlan overlay, Wireguard enabled)
Orchestrator version (e.g. kubernetes, mesos, rkt):
Kubernetes v1.24.6.
Operating System and version:
Ubuntu 20.04.6 LTS, kernel version 5.4.0-150-generic

@AlexeyKasatkin closing this issue as inactive, feel free to reach out with more detailed information if you need it to be reopened...


Fix documentation build

These commits address  two build failures when making in /docs.
Resolves SR-5049.
@swift-ci Please smoke test

Thanks!  Since this doesn't seem to be caught by CI, I'll clone your changes locally to verify.

@swift-ci please smoke test

Alright, I ran a sphinx build on master and against your branch was able to confirm this fix works.
⛵


[Bug Report]: BadRequest - Alert scope is invalid when creating metric alert for availability web test

Describe the bug
I'm writing a appService.bicep file for creating an App Service with an availability web test (ping) & a metric alert for monitoring and alerting the uptime. The deployment is failed with the error message: BadRequest - Alert scope is invalid.
Link to the reference Bicep file: https://github.com/Azure/ResourceModules/blob/main/modules/insights/metric-alerts/main.bicep
To reproduce
When calling webTest and metricAlert as 2 modules from main.bicep, if the alertCriteriaType is & criterias is an array, an error appears as BadRequest - Alert scope is invalid or {"code":"BadRequest","message":"Alert scope is invalid. Activity ID: xx."}.
Code snippet
metricAlerts.bicep
resource metricAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = {
  name: name
  location: location
  properties: {
    scopes: scopes
    criteria: {
      'odata.type': any(alertCriteriaType)
      allOf: criterias
    }
  }
}

main.bicep
module pingAlertRule 'main.bicep' = {
  name: alertRuleName
  params: {
    name: alertRuleName
    location: 'global'
    tags: {
      'hidden-link:${appInsightResourceId}': 'Resource'
      'hidden-link:${webTest.id}': 'Resource'
    }
    scopes: [
      webTest.id
      appInsightResourceId
    ]
    alertCriteriaType: 'Microsoft.Azure.Monitor.WebtestLocationAvailabilityCriteria'**
    criterias: [
      {
        webTestId: webTest.id
        componentId: appInsightResourceId
        failedLocationCount: 3
      }
    ]
  }
}

Relevant log output
BadRequest - Alert scope is invalid or {"code":"BadRequest","message":"Alert scope is invalid. Activity ID: 9c0a401c-3e64-4764-8420-9b95002cb361."}.

Hey @vienleidl,
this issue fell victim to the AVM migration issues. However, if it's still revelant we should follow-up.
Can you recall if this was related to the CARML modules for Metric Alert & WebTest? It's a bit hard to tell from the description. If not (i.e. you created your own implementation) it would be better resolved via a support ticket rather than this library. Please advice :)

Closing as there has not been a respose (yet). However, @vienleidl feel free to re-open the issue again - or - even better create it as an issue in the Azure-Verified-Modules (https://github.com/Azure/bicep-registry-modules) repository if it's a module issue :)


License ?

Hello, under what license is this project released under ? Thank-you.

Hey, sorry I never got to do this. Have added the standard MIT license.


RFE : Skip security questions on password reset

I'm currently using the new Password Management functionality in CAS 5.1 (for a JDBC backend) and cannot use the security questions as these are currently not present in the database. The current implementation assumes that there is at least one security question and throws an error if none are present.
I've successfully replaced the pswdreset-webflow.xml in CAS 5.0.1 (with my own tweaks to get password management working over JDBC) however with 5.1 RC2 spring doesn't pick up my new webflow when applied to an overlay project. The file is in src/main/resources/webflow/pswdreset.
Is it possible without writing my own webflow configuration java classes to have the xml files replace the base ones when using an overlay?
An alternative is to update the flow to not ask security questions (or always succeed) if none are present instead of throwing an error

Is it possible without writing my own webflow configuration java classes to have the xml files replace the base ones when using an overlay?

Note the big yellow box:
https://apereo.github.io/cas/5.0.x/installation/Webflow-Customization.html#webflow-auto-configuration

An alternative is to update the flow to not ask security questions (or always succeed) if none are present instead of throwing an error

This is a much better alternative, according to the big yellow box :)

I would agree, the better way would be to modify the code :) Slightly easier to initially update the webflow document though...

This is now done. You can try to disable support for security questions.


Cannot add a new language from settings

Cannot add a new language from settings and use the same for the agent

Pulled from the master - v0.31.1
Windows 10 Pro - Version 1903
Running Locally
Firefox 75.0 (64-bit)

Noticing, that the languages can be added under the Settings: System configuration > General section. I assume that, the Agent Languages corresponds to Rasa NLU language support. And the UI language is only the locale configuration for the Articulate UI. Here are the steps I did:

Updated the Agent Languages by adding Arabic:

[
  {
    "value": "de",
    "text": "Deutsch"
  },
  {
    "value": "en",
    "text": "English"
  },
  {
    "value": "es",
    "text": "Español"
  },
  {
    "value": "fr",
    "text": "Française"
  },
  {
    "value": "pt",
    "text": "Portugues"
  },
  {
    "value": "ar",
    "text": "Arabic"
  }
]

Saved the settings and tried creating a new agent, selecting Arabic as the language from the ComboBox. But could not create the agent as the Save button did not work. And received the following message on the chat window instead:

Error: There was an error creating your agent.

Checked the logs from the docker by supplying docker logs articulate_api_1, and found the following message:

ValidationError: child "language" fails because ["language" must be one of [de, en, es, fr, pt]]

I could not proceed hereafter. Is it that UI language needs to be updated to the respective Agent Language? Any help is appreciated. Thank you!

@alshell7 do Rasa and spaCy support arabic?
That setting really only applies to spaCy and duckling. and If you're using the default pipelines it only has an impact if you're using system entities from spaCy or Duckling.
@dcalvom did you type something up on adding a new language, I was thinking we had a guide for it someplace. Off the top of my head things that would need touched:

UI menu
API validation
Rasa Docker image

Yes Rasa does support arabic. As from this PR. Usually using the Tensorflow pipeline, should get working as well. But it's again optional, the DIET Classifier for Intent classification and Duckling are a good catch together by default.

We are using version 0.14.4 of Rasa, that is the last version where they supported multiple models, which Articulate requires for now. the DIET classifier isn't an option here, as that's a fairly recent introduction.

we do have the tensorfzlow pipeline, which to use a different language with that nothing is required, just type your sayings in the language you want. The drop down only has an impact for space and duckling.

How to implement arabic for intent classification? I'm tired of running through PR issues and still not able to figure it out-
History of my navigation ->
PR #1095 says we can get Arabic support but here it @alshell7 says we cannot implement it?
I have the rasa version - '1.10.2' .
The settings in the config.yml file show that we should involve tensorflow embeddings? How do we do that? Can I get an example of the config file to support arabic in this version of rasa please?


[FLINK-5863][queryable state] Add the serialization of list states in KvStateRequestSerializer

Add serializeList() in KvStateRequestSerialization
Modify the unit tests of KvStateRequestSerialization, without the access to protected methods.
Move KvStateRequestSerializationRocksDBTest from package org.apache.flink.test.query to org.apache.flink.contrib.streaming.state.

If I understand this correctly, this gets rid of duplicated code. I think this is in general very valuable, but the problem is queryable state right now is that we need to refactor this for 1.3 anyways. Currently, too many flink-runtime components are exposed to the user. I'm working on a FLIP to improve the user APIs for 1.3 and deprecated (or maybe even remove) the current APIs. This will therefore become obsolete. What do you think? Should we close this PR and issue and you help on the proposed changes instead?

The PR is just some cleaning of the code. Now that we are planning to refactor the implementation, I agree to close the PR and I am very willing to contribute to the FLIP.


drivers: sensor: mc3419: Change the TRIGGER config to a typical

Because MC3419's TRIGGER's Kconfig was different from the typical configuration,
the conf file settings were not correctly applied.
The Kconfig configuration has been revised to be set in conjunction with
MC3419_TRIGGER_OWN_THREAD, even if MC3419_TRIGGER is not explicitly specified.

Rebase done.

@jeppenodgaard
Could you revisit this if you have time?


provide constants for deviceType

Description
Fixes #1296
This is a quick pass as I don't have the time right now to figure out how this package is built. Hopefully I'll have some free time next week to look into it if nobody else is able to take a look.

Added yourNewMethodName() that allows ...
Compatibility

OS
Implemented

iOS
✅❌

Android
✅❌

Windows
✅❌

Checklist

[ ] I have tested this on a device/simulator for each compatible OS
[ ] I added the documentation in README.md
[ ] I updated the typings files (privateTypes.ts, types.ts)
[ ] I added a sample use of the API (example/App.js)

doing some janitor work - can reopen if interested, but appears abandoned, or just slow communication (happy to reopen if so)


Microsoft Teams crashes Pock

Describe the bug
If you try to go to MS Teams via Pock over the Touchbar then Pock crashes.
How to reproduce
Run Microsoft Teams and Click on Teams Icon in Touchbar.
Expected behavior
MS Teams should open and not Crash Pock
Versions:

macOS version: 10.14.6
Pock version:  0.6
MS Teams: <IP_ADDRESS>68

Yep - me too - this is quite annoying. I find when Teams is closed nothing happens when tapping on the icon. When Teams is running and I try to switch to activate it then it crashes Pock

Happens to me as well.  When Pock doesn't crash, I normally see a generic app icon in place of the Teams icon, and upon occasion the icon continually bounces in Pock.

Teams use an extra app that handles the notifications.
It is called anders has a different app icon.
A workaround can be found here.


Update retire.md

Retirement data is updated to reflect the latest guidelines from retirement council.

@SunilRSanjeev : Thanks for your contribution! The author(s) have been notified to review your proposed change. @SunilSanjeev

#label:"aq-pr-triaged"

@SunilRSanjeev, Can you make the change in the private repo? I sent you a mail with details.
#please-close


WebSocketFactory.createSocket causes an exception on Android

Here is the stack:
at java.net.InetAddress.lookupHostByName(InetAddress.java:431)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getByName(InetAddress.java:305)
at java.net.InetSocketAddress.(InetSocketAddress.java:100)
at java.net.InetSocketAddress.(InetSocketAddress.java:85)
at com.neovisionaries.ws.client.WebSocketFactory.createDirectRawSocket(WebSocketFactory.java:621)
at com.neovisionaries.ws.client.WebSocketFactory.createRawSocket(WebSocketFactory.java:577)
at com.neovisionaries.ws.client.WebSocketFactory.createSocket(WebSocketFactory.java:509)
at com.neovisionaries.ws.client.WebSocketFactory.createSocket(WebSocketFactory.java:488)
Specifically the WebSocketFactory.java:621: SocketAddress address = new InetSocketAddress(host, port); which causes a network call. It kind of defeats the purpose of having connectAsynchronously.
The fix seems to be easy. Instead of WebSocketFactory.java:621
    // The address to connect to.
    SocketAddress address = new InetSocketAddress(host, port);

    // Create an instance that will execute the task to connect to the server later.
    return new SocketConnector(socket, address, timeout);

do
    // Create an instance that will execute the task to connect to the server later.
    return new SocketConnector(socket, host, port, timeout);

Then have SocketConnector call  new InetSocketAddress(host, port); on the first call to connect().

Thank you for your nice report. I've fixed the problem and released a new version 1.22 including the fix. (The issue could have been found soon if I had tried it on Android. Sorry.)

Just verified on Android API 23. Confirming that it's fixed now. Thanks!


Fix for issue #39.

This pull request is intended to fix issue #39 (ValueError: Layer weight shape (3, 3, 3, 64) not compatible with provided weight shape (64, 3, 3, 3) ) and to make the image-analogies package compatible with keras versions 2.0.0 and above.
I only made changes to the vgg16.py file.
The newly added code does the following:

It checks if your version of keras is version '2.0.0' or above;

If your version of keras is version '2.0.0' or above, then it (1) converts each element x of the list 'weights' into a numpy array, (2) transposes each of those arrays, and (3) saves the list of transposed arrays back to the 'weights' list.
     weights_T = [np.array(x).T for x in weights]
     weights = weights_T

If your version of keras is version not '2.0.0' or above, the 'weights' list is left unchanged; the elements of 'weights' are left untransposed.

Transposing the weights is necessary for compatibility with keras is version '2.0.0' or above.
The code should still be compatible with earlier versions of keras before version '2.0.0'.

This worked for me as well -- many thanks!

why i run the make_image_analoy.py,the result is that, i don't know how to solve it? thanks.


Add basic Dockerfile

This pull request...

[ ] Fixes a bug
[x] Introduces a new feature
[ ] Improves an existing feature
[ ] Boosts code quality or performance

Description
This PR adds a very basic Dockerfile. Packaged it for myself, but someone else might also find it useful.
It uses multi-stage builds, greatly decreasing the size of the final image. If you also want to provide docker image downloads, both docker-hub and quay.io has automatic builders so there isn't need to configure much.
I've decided to put the jar in the rootfs because I never really know of a better UNIXy place. Open to suggestions.

I chose Java 11 because it's the latest LTS release. There's no worry about it not working on some systems because, well, containers. Unless I just didn't find the case where it breaks yet. Java 11 has plenty of runtime improvements like GC, although I don't think Music Bot creates enough allocations to worry about it.
I'd rather avoid copying the compiled jar from the host - this limits amount of uses for the Dockerfile itself.
I tried to cache dependencies etc. I don't have any ideas on further limiting when the source is rebuilt.
Thanks a lot! I also noticed the bot creates more data than I expected, so in my deployment I've moved everything.

Also probably should switch to some random, non-root user in the Dockerfile.

1. I chose Java 11 because it's the latest LTS release. There's no worry about it not working on some systems because, well, containers.

no its not the latest LTS release but whatever.

3. I tried to cache dependencies etc. I don't have any ideas on further limiting when the source is rebuilt.

maybe check if the jar exists in your workdir, if not run maven for building the jar, else skip to executing the jar.

has been edited

@Prof-Bloodstone Sorry if I came off combative.  My response was more directed at Sanduhr32's requests to fix the docker file when what you have is pretty standard.


Gramps XML Import

Gramps XML is the Extensible Markup Language (XML) format designed for storing Gramps data. The goal is to have a fully portable, human- and machine-readable XML format so that the data can be read and written without any loss.
https://www.gramps-project.org/wiki/index.php/Gramps_XML#:~:text=Gramps XML is the Extensible,and written without any loss.

ChengZe started work on it.


Server-side HTML does not contain styles if a route is not lazy

Thanks for your work!
If you set the route as: { path: '/home', Component: Home } (without lazy loading), then server-side HTML does not contain styles in DEV mode.
Changes compared to the demo app:
https://github.com/Lomray-Software/vite-template/compare/prod...grothendeick:vite-template:prod
Reproduction:
https://stackblitz.com/~/github.com/grothendeick/vite-template

@MatthewPattell,
thanks for the quick response.
Now it's working, but only if the non-lazy route is specified last in the file:
{
  path: RouteManager.path('notLazy'),
  Component: NotLazyPage,
},
{
  path: RouteManager.path('notLazy2'),
  Component: NotLazyPage2,
}

It works for NotLazyPage2, but not for NotLazyPage.

@grothendeick ah, you can check fix this in v2.0.0-beta.3

@grothendeick now it's part of v2.0.0

@MatthewPattell, v2.0.0 gives the error:
Error: Transform failed with 1 error:
C:/repositories/vite-template-prod/src/routes/index.ts:38:75: ERROR: Expected "]" but found ":"
    at failureErrorWithLog (c:\repositories\vite-template-prod\node_modules\esbuild\lib\main.js:1650:15)
    at c:\repositories\vite-template-prod\node_modules\esbuild\lib\main.js:848:29
    at responseCallbacks.<computed> (c:\repositories\vite-template-prod\node_modules\esbuild\lib\main.js:703:9)
    at handleIncomingPacket (c:\repositories\vite-template-prod\node_modules\esbuild\lib\main.js:763:9)
    at Socket.readFromStdout (c:\repositories\vite-template-prod\node_modules\esbuild\lib\main.js:679:7)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:324:12)
    at readableAddChunk (node:internal/streams/readable:297:9)
    at Readable.push (node:internal/streams/readable:234:10)
    at Pipe.onStreamRead (node:internal/stream_base_commons:190:23) {
  errors: [Getter/Setter],
  warnings: [Getter/Setter],
  frame: '\n' +
    '\x1B[33mExpected "]" but found ":"\x1B[39m\n' +
    "36 |          lazy: ()=>n(() => import('@pages/redirect'),'@pages/redirect'),\n" +
    '37 |        },\n' +
    "38 |        { path: RouteManager.path('notLazy'), Component: NotLazyPage },pathId: '@pages/not-lazy',\n" +
    '   |                                                                             ^\n' +
    "39 |        { path: RouteManager.path('notLazy2'), Component: NotLazyPage2 },pathId: '@pages/not-lazy',\n" +
    '40 |      ],\n',
  loc: {
    column: 75,
    file: 'C:/repositories/vite-template-prod/src/routes/index.ts',
    length: 1,
    line: 38,
    lineText: "      { path: RouteManager.path('notLazy'), Component: NotLazyPage },pathId: '@pages/not-lazy',",
    namespace: '',
    suggestion: ']'
  },
  plugin: 'vite:esbuild',
  id: 'C:/repositories/vite-template-prod/src/routes/index.ts',
  pluginCode: "import n from '@lomray/vite-ssr-boost/helpers/import-route';import type { TRouteObject } from '@lomray/vite-ssr-boost/interfaces/route-object';\n" +
    "import AppLayout from '@components/layouts/app';\n" +
    "import Home from '@pages/home';\n" +
    "import NotFound from '@pages/not-found';\n" +
    "import NotLazyPage from '@pages/not-lazy';\n" +
    "import NotLazyPage2 from '@pages/not-lazy';\n" +
    "import RouteManager from '@services/route-manager';\n" +
    "import DetailsRoutes from './details';\n" +
    '\n' +
    '/**\n' +
    ' * Application routes\n' +
    ' */\n' +
    'const routes: TRouteObject[] = [\n' +
    '  {\n' +
    '    ErrorBoundary: NotFound,\n' +
    "    Component: AppLayout,pathId: '@components/layouts/app',\n" +
    '    children: [\n' +
    '      {\n' +
    '        index: true,\n' +
    "        Component: Home,pathId: '@pages/home',\n" +
    '      },\n' +
    '      {\n' +
    "        path: RouteManager.path('details'),\n" +
    '        children: DetailsRoutes,\n' +
    '      },\n' +
    '      {\n' +
    "        path: RouteManager.path('errorBoundary'),\n" +
    "        lazy: ()=>n(() => import('@pages/error-boundary'),'@pages/error-boundary'),\n" +
    '      },\n' +
    '      {\n' +
    "        path: RouteManager.path('nestedSuspense'),\n" +
    "        lazy: ()=>n(() => import('@pages/nested-suspense'),'@pages/nested-suspense'),\n" +
    '      },\n' +
    '      {\n' +
    "        path: RouteManager.path('redirect'),\n" +
    "        lazy: ()=>n(() => import('@pages/redirect'),'@pages/redirect'),\n" +
    '      },\n' +
    "      { path: RouteManager.path('notLazy'), Component: NotLazyPage },pathId: '@pages/not-lazy',\n" +
    "      { path: RouteManager.path('notLazy2'), Component: NotLazyPage2 },pathId: '@pages/not-lazy',\n" +
    '    ],\n' +
    '  },\n' +
    '];\n' +
    '\n' +
    'export default routes;\n'
}

Node.js v18.12.1

It looks like pathId  is inserted in the wrong place:
    "      { path: RouteManager.path('notLazy'), Component: NotLazyPage },pathId: '@pages/not-lazy',\n" +
    "      { path: RouteManager.path('notLazy2'), Component: NotLazyPage2 },pathId: '@pages/not-lazy',\n"

@grothendeick Oh, I didn't consider code formatting. Well, now I've tried to account for as many cases as possible. v2.0.1