1
0
mirror of https://github.com/flutter/samples.git synced 2026-06-28 00:57:25 +00:00

Dart 3.9 / Flutter 3.35 [first LLM release] (#2714)

I got carried away with Gemini and basically rewrote CI and the release
process for the new LLM reality. This work was largely completed by
Gemini.

- Bump all SDK versions to the current beta (3.9.0-0)
- Run `flutter channel beta`
- Wrote `ci_script.dart` to replace the bash scripts
- Converted repository to pub workspace #2499 
- Added llm.md and release.md
- Added redirect for deprecated Samples Index

## Pre-launch Checklist

- [x] I read the [Flutter Style Guide] _recently_, and have followed its
advice.
- [x] I signed the [CLA].
- [x] I read the [Contributors Guide].
- [x] I have added sample code updates to the [changelog].
- [x] I updated/added relevant documentation (doc comments with `///`).
This commit is contained in:
Eric Windmill
2025-08-14 12:26:24 -07:00
committed by GitHub
parent 0aa5415d5e
commit 2999d738b8
410 changed files with 28166 additions and 27661 deletions

View File

@@ -39,20 +39,18 @@ class _PhotoDetailsState extends State<PhotoDetails> {
uri: Uri.parse(
'https://unsplash.com/@${widget.photo.user!.username}?utm_source=$unsplashAppName&utm_medium=referral',
),
builder:
(context, followLink) => HyperlinkButton(
onPressed: followLink,
child: Text(widget.photo.user!.name),
),
builder: (context, followLink) => HyperlinkButton(
onPressed: followLink,
child: Text(widget.photo.user!.name),
),
),
const Text('on'),
Link(
uri: _unsplashHomepage,
builder:
(context, followLink) => HyperlinkButton(
onPressed: followLink,
child: const Text('Unsplash'),
),
builder: (context, followLink) => HyperlinkButton(
onPressed: followLink,
child: const Text('Unsplash'),
),
),
],
);

View File

@@ -48,13 +48,12 @@ class _PhotoSearchDialogState extends State<PhotoSearchDialog> {
),
actions: [
FilledButton(
onPressed:
_searchEnabled
? () {
widget.callback(_controller.text);
Navigator.of(context).pop();
}
: null,
onPressed: _searchEnabled
? () {
widget.callback(_controller.text);
Navigator.of(context).pop();
}
: null,
child: const Text('Search'),
),
Button(

View File

@@ -29,16 +29,15 @@ class PolicyDialog extends StatelessWidget {
fontWeight: FontWeight.bold,
color: Colors.blue.normal,
),
recognizer:
TapGestureRecognizer()
..onTap = () async {
final url = Uri.parse(
'https://policies.google.com/terms',
);
if (await url_launcher.canLaunchUrl(url)) {
await url_launcher.launchUrl(url);
}
},
recognizer: TapGestureRecognizer()
..onTap = () async {
final url = Uri.parse(
'https://policies.google.com/terms',
);
if (await url_launcher.canLaunchUrl(url)) {
await url_launcher.launchUrl(url);
}
},
),
],
),
@@ -55,14 +54,13 @@ class PolicyDialog extends StatelessWidget {
fontWeight: FontWeight.bold,
color: Colors.blue.normal,
),
recognizer:
TapGestureRecognizer()
..onTap = () async {
final url = Uri.parse('https://unsplash.com/terms');
if (await url_launcher.canLaunchUrl(url)) {
await url_launcher.launchUrl(url);
}
},
recognizer: TapGestureRecognizer()
..onTap = () async {
final url = Uri.parse('https://unsplash.com/terms');
if (await url_launcher.canLaunchUrl(url)) {
await url_launcher.launchUrl(url);
}
},
),
],
),

View File

@@ -144,7 +144,9 @@ class _SplitState extends State<Split> {
child: DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).dividerColor,
borderRadius: BorderRadius.circular(Split.dividerMainAxisSize),
borderRadius: BorderRadius.circular(
Split.dividerMainAxisSize,
),
),
child: SizedBox(
height: isHorizontal ? 2.0 : Split.dividerMainAxisSize - 2.0,

View File

@@ -68,13 +68,12 @@ class _UnsplashDialog extends StatelessWidget {
children: [
TextSpan(
text: 'Unsplash',
recognizer:
TapGestureRecognizer()
..onTap = () async {
if (!await launchUrl(_unsplashHomepage)) {
throw 'Could not launch $_unsplashHomepage';
}
},
recognizer: TapGestureRecognizer()
..onTap = () async {
if (!await launchUrl(_unsplashHomepage)) {
throw 'Could not launch $_unsplashHomepage';
}
},
style: TextStyle(color: Colors.blue),
),
const TextSpan(
@@ -87,16 +86,18 @@ class _UnsplashDialog extends StatelessWidget {
),
TextSpan(
text: 'how Unsplash collects and uses data',
recognizer:
TapGestureRecognizer()
..onTap = () async {
if (!await launchUrl(_unsplashPrivacyPolicy)) {
throw 'Could not launch $_unsplashPrivacyPolicy';
}
},
recognizer: TapGestureRecognizer()
..onTap = () async {
if (!await launchUrl(_unsplashPrivacyPolicy)) {
throw 'Could not launch $_unsplashPrivacyPolicy';
}
},
style: TextStyle(color: Colors.blue),
),
const TextSpan(text: '.', style: TextStyle(color: Colors.grey)),
const TextSpan(
text: '.',
style: TextStyle(color: Colors.grey),
),
],
),
),

View File

@@ -44,34 +44,33 @@ class _UnsplashSearchContentState extends State<UnsplashSearchContent> {
),
),
secondChild: Center(
child:
photoSearchModel.selectedPhoto != null
? PhotoDetails(
photo: photoSearchModel.selectedPhoto!,
onPhotoSave: (photo) async {
final saveLocation = await getSaveLocation(
suggestedName: '${photo.id}.jpg',
acceptedTypeGroups: [
const XTypeGroup(
label: 'JPG',
extensions: ['jpg'],
mimeTypes: ['image/jpeg'],
),
],
child: photoSearchModel.selectedPhoto != null
? PhotoDetails(
photo: photoSearchModel.selectedPhoto!,
onPhotoSave: (photo) async {
final saveLocation = await getSaveLocation(
suggestedName: '${photo.id}.jpg',
acceptedTypeGroups: [
const XTypeGroup(
label: 'JPG',
extensions: ['jpg'],
mimeTypes: ['image/jpeg'],
),
],
);
if (saveLocation != null) {
final fileData = await photoSearchModel.download(
photo: photo,
);
if (saveLocation != null) {
final fileData = await photoSearchModel.download(
photo: photo,
);
final photoFile = XFile.fromData(
fileData,
mimeType: 'image/jpeg',
);
await photoFile.saveTo(saveLocation.path);
}
},
)
: Container(),
final photoFile = XFile.fromData(
fileData,
mimeType: 'image/jpeg',
);
await photoFile.saveTo(saveLocation.path);
}
},
)
: Container(),
),
);
}
@@ -85,26 +84,25 @@ class _UnsplashSearchContentState extends State<UnsplashSearchContent> {
return TreeViewItem(
content: Text(searchEntry.query),
children:
searchEntry.photos
.map<TreeViewItem>(
(photo) => TreeViewItem(
content: Semantics(
button: true,
onTap: () => selectPhoto(photo),
label: labelForPhoto(photo),
excludeSemantics: true,
child: GestureDetector(
onTap: () => selectPhoto(photo),
child: Text(
labelForPhoto(photo),
style: const TextStyle(color: Colors.black),
),
),
children: searchEntry.photos
.map<TreeViewItem>(
(photo) => TreeViewItem(
content: Semantics(
button: true,
onTap: () => selectPhoto(photo),
label: labelForPhoto(photo),
excludeSemantics: true,
child: GestureDetector(
onTap: () => selectPhoto(photo),
child: Text(
labelForPhoto(photo),
style: const TextStyle(color: Colors.black),
),
),
)
.toList(),
),
),
)
.toList(),
);
}
}