Merge in the flutter gallery ()

pull/179/head
rami-a 5 years ago committed by GitHub
parent 428041b253
commit 6673acc6d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,30 @@
# Flutter Gallery
Flutter Gallery is a resource to help developers evaluate and use Flutter.
It is a collection of material design widgets, behaviors, and vignettes
implemented with Flutter. We often get asked how one can see Flutter in
action, and this gallery demonstrates what Flutter provides and how it
behaves in the wild.
## Supported Platforms
The Flutter Gallery application has been built to support multiple platforms. This includes:
* Android
* iOS
* web
* macOS
* Linux
* Windows
That being said, extra steps must be taken to [enable Desktop support](https://github.com/flutter/flutter/wiki/Desktop-shells#tooling).
Additionally, the UI adapts between mobile and desktop layouts regardless of the platform it runs on. This is determined based on window size as outlined in [adaptive.dart](https://github.com/material-components/material-components-flutter-gallery/blob/master/gallery/lib/layout/adaptive.dart).
## To include a new splash animation
1. Convert your animation to a `.gif` file. Ideally, use a background color of `0xFF030303` to ensure the animation blends into the background of the app.
2. Add your new `.gif` file to the assets directory under `assets/splash_effects`. Ensure the name follows the format `splash_effect_$num.gif`. The number should be the next number after the current largest number in the repository.
3. Update the map `_effectDurations` in [splash.dart](https://github.com/material-components/material-components-flutter-gallery/blob/master/gallery/lib/pages/splash.dart) to include the number of the new `.gif` as well as its estimated duration. The duration is used to determine how long to display the splash animation at launch.

@ -0,0 +1,11 @@
# Files and directories created by pub
.dart_tool/
.packages
# Remove the following pattern if you wish to check in your lock file
pubspec.lock
# Conventional directory for build outputs
build/
# Directory created by dartdoc
doc/api/

@ -0,0 +1,3 @@
## 1.0.0
- Initial version

@ -0,0 +1,55 @@
A command-line application to highlight dart source code.
## Overview
Code segments are highlighted before the app is compiled.
This is done because the highlighting process can take 300ms to finish, creating a noticeable delay when the demo switches to code page.
The highlighter takes all files in the `gallery/lib/demos/` folder and scans each.
Highlighted code widgets are stored in the `gallery/lib/codeviewer/code_segments.dart` file.
Under the root directory, run `make update-code-segments` to run the highlighter.
Wrap a block of code with lines `// BEGIN yourDemoName` and `// END` to mark it for highlighting. The block in between, as well as any copyright notice and imports at the beginning of the file, are automatically taken and highlighted, and stored as `static TextSpan yourDemoName(BuildContext context)` in `gallery/lib/codeviewer/code_segments.dart`.
To display the code, go to `gallery/lib/data/demos.dart`, and add `code: CodeSegments.yourDemoName,` to your `GalleryDemoConfiguration` object.
## Multiple blocks of code
Use the following method to join multiple blocks of code into a single segment:
```
// BEGIN yourDemo#2
a();
// END
b();
// BEGIN yourDemo#1
c();
// END
```
The generated code will be
```
c();
a();
```
Code blocks can nest or overlap. In these cases, specify which file(s) to `END`.
The following source file
```
// BEGIN demoOne
a();
// BEGIN demoTwo
b();
// END demoOne
c();
// END demoTwo
```
will create the following segments:
(demoOne)
```
a();
b();
```
(demoTwo)
```
b();
c();
```

@ -0,0 +1,39 @@
# Defines a default set of lint rules enforced for
# projects at Google. For details and rationale,
# see https://github.com/dart-lang/pedantic#enabled-lints.
include: package:pedantic/analysis_options.yaml
# For lint rules and documentation, see http://dart-lang.github.io/linter/lints.
# Uncomment to specify additional rules.
# linter:
# rules:
# - camel_case_types
analyzer:
# exclude:
# - path/to/excluded/files/**
linter:
rules:
- avoid_types_on_closure_parameters
- avoid_void_async
- await_only_futures
- camel_case_types
- cancel_subscriptions
- close_sinks
- constant_identifier_names
- control_flow_in_finally
- empty_statements
- hash_and_equals
- implementation_imports
- non_constant_identifier_names
- package_api_docs
- package_names
- package_prefixed_library_names
- test_types_in_equals
- throw_in_finally
- unnecessary_brace_in_string_interps
- unnecessary_getters_setters
- unnecessary_new
- unnecessary_statements
- directives_ordering

@ -0,0 +1,12 @@
// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:codeviewer_cli/segment_generator.dart';
main(List<String> arguments) {
writeSegments(
sourceDirectoryPath: '../gallery/lib/demos',
targetFilePath: '../gallery/lib/codeviewer/code_segments.dart',
);
}

@ -0,0 +1,412 @@
// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:string_scanner/string_scanner.dart';
abstract class SyntaxPrehighlighter {
List<CodeSpan> format(String src);
}
class DartSyntaxPrehighlighter extends SyntaxPrehighlighter {
DartSyntaxPrehighlighter() {
_spans = <_HighlightSpan>[];
}
static const List<String> _keywords = <String>[
'abstract',
'as',
'assert',
'async',
'await',
'break',
'case',
'catch',
'class',
'const',
'continue',
'default',
'deferred',
'do',
'dynamic',
'else',
'enum',
'export',
'external',
'extends',
'factory',
'false',
'final',
'finally',
'for',
'get',
'if',
'implements',
'import',
'in',
'is',
'library',
'new',
'null',
'operator',
'part',
'rethrow',
'return',
'set',
'static',
'super',
'switch',
'sync',
'this',
'throw',
'true',
'try',
'typedef',
'var',
'void',
'while',
'with',
'yield',
];
static const List<String> _builtInTypes = <String>[
'int',
'double',
'num',
'bool',
];
String _src;
StringScanner _scanner;
List<_HighlightSpan> _spans;
@override
List<CodeSpan> format(String src) {
_src = src;
_scanner = StringScanner(_src);
if (_generateSpans()) {
// Successfully parsed the code
final List<CodeSpan> formattedText = <CodeSpan>[];
int currentPosition = 0;
for (_HighlightSpan span in _spans) {
if (currentPosition != span.start) {
formattedText
.add(CodeSpan(text: _src.substring(currentPosition, span.start)));
}
formattedText
.add(CodeSpan(type: span.type, text: span.textForSpan(_src)));
currentPosition = span.end;
}
if (currentPosition != _src.length) {
formattedText
.add(CodeSpan(text: _src.substring(currentPosition, _src.length)));
}
return formattedText;
} else {
// Parsing failed, return with only basic formatting
return [CodeSpan(type: _HighlightType.base, text: src)];
}
}
bool _generateSpans() {
int lastLoopPosition = _scanner.position;
while (!_scanner.isDone) {
// Skip White space
_scanner.scan(RegExp(r'\s+'));
// Block comments
if (_scanner.scan(RegExp(r'/\*(.|\n)*\*/'))) {
_spans.add(_HighlightSpan(
_HighlightType.comment,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// Line comments
if (_scanner.scan('//')) {
final int startComment = _scanner.lastMatch.start;
bool eof = false;
int endComment;
if (_scanner.scan(RegExp(r'.*\n'))) {
endComment = _scanner.lastMatch.end - 1;
} else {
eof = true;
endComment = _src.length;
}
_spans.add(_HighlightSpan(
_HighlightType.comment,
startComment,
endComment,
));
if (eof) {
break;
}
continue;
}
// Raw r"String"
if (_scanner.scan(RegExp(r'r".*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// Raw r'String'
if (_scanner.scan(RegExp(r"r'.*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// Multiline """String"""
if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// Multiline '''String'''
if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// "String"
if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// 'String'
if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// Double
if (_scanner.scan(RegExp(r'\d+\.\d+'))) {
_spans.add(_HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// Integer
if (_scanner.scan(RegExp(r'\d+'))) {
_spans.add(_HighlightSpan(_HighlightType.number,
_scanner.lastMatch.start, _scanner.lastMatch.end));
continue;
}
// Punctuation
if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) {
_spans.add(_HighlightSpan(
_HighlightType.punctuation,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// Meta data
if (_scanner.scan(RegExp(r'@\w+'))) {
_spans.add(_HighlightSpan(
_HighlightType.keyword,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
continue;
}
// Words
if (_scanner.scan(RegExp(r'\w+'))) {
_HighlightType type;
String word = _scanner.lastMatch[0];
if (word.startsWith('_')) {
word = word.substring(1);
}
if (_keywords.contains(word)) {
type = _HighlightType.keyword;
} else if (_builtInTypes.contains(word)) {
type = _HighlightType.keyword;
} else if (_firstLetterIsUpperCase(word)) {
type = _HighlightType.klass;
} else if (word.length >= 2 &&
word.startsWith('k') &&
_firstLetterIsUpperCase(word.substring(1))) {
type = _HighlightType.constant;
}
if (type != null) {
_spans.add(_HighlightSpan(
type,
_scanner.lastMatch.start,
_scanner.lastMatch.end,
));
}
}
// Check if this loop did anything
if (lastLoopPosition == _scanner.position) {
// Failed to parse this file, abort gracefully
return false;
}
lastLoopPosition = _scanner.position;
}
_simplify();
return true;
}
void _simplify() {
for (int i = _spans.length - 2; i >= 0; i -= 1) {
if (_spans[i].type == _spans[i + 1].type &&
_spans[i].end == _spans[i + 1].start) {
_spans[i] = _HighlightSpan(
_spans[i].type,
_spans[i].start,
_spans[i + 1].end,
);
_spans.removeAt(i + 1);
}
}
}
bool _firstLetterIsUpperCase(String str) {
if (str.isNotEmpty) {
final String first = str.substring(0, 1);
return first == first.toUpperCase();
}
return false;
}
}
enum _HighlightType {
number,
comment,
keyword,
string,
punctuation,
klass,
constant,
base,
}
class _HighlightSpan {
_HighlightSpan(this.type, this.start, this.end);
final _HighlightType type;
final int start;
final int end;
String textForSpan(String src) {
return src.substring(start, end);
}
}
class CodeSpan {
CodeSpan({this.type = _HighlightType.base, this.text});
final _HighlightType type;
final String text;
@override
String toString() {
return 'TextSpan('
'style: codeStyle.${_styleNameOf(type)}, '
"text: '${_escape(text)}'"
')';
}
}
String _styleNameOf(_HighlightType type) {
switch (type) {
case _HighlightType.number:
return 'numberStyle';
case _HighlightType.comment:
return 'commentStyle';
case _HighlightType.keyword:
return 'keywordStyle';
case _HighlightType.string:
return 'stringStyle';
case _HighlightType.punctuation:
return 'punctuationStyle';
case _HighlightType.klass:
return 'classStyle';
case _HighlightType.constant:
return 'constantStyle';
case _HighlightType.base:
return 'baseStyle';
}
return '';
}
String _escape(String text) {
StringBuffer escapedText = StringBuffer();
for (final char in text.runes) {
if (char < 0x20 ||
char >= 0x7F ||
char == 0x22 ||
char == 0x24 ||
char == 0x27 ||
char == 0x5C) {
if (char <= 0xffff) {
escapedText.write("\\u${_encodeAndPad(char)}");
} else {
escapedText.write("\\u{${_encode(char)}}");
}
} else {
escapedText.write(String.fromCharCode(char));
}
}
return escapedText.toString();
}
String _encode(int charCode) {
return charCode.toRadixString(16);
}
String _encodeAndPad(int charCode) {
String encoded = _encode(charCode);
return '0' * (4 - encoded.length) + encoded;
}

@ -0,0 +1,266 @@
// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert';
import 'dart:io';
import 'prehighlighter.dart';
const _globalPrologue =
'''// This file is automatically generated by codeviewer_cli.
// Do not edit this file.
// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:gallery/codeviewer/code_style.dart';
class CodeSegments {
''';
const _globalEpilogue = '}\n';
final Pattern beginSubsegment = RegExp(r'//\s+BEGIN');
final Pattern endSubsegment = RegExp(r'//\s+END');
enum _FileReadStatus {
comments,
imports,
finished,
}
/// Returns the new status of the scanner whose previous status was
/// [oldStatus], after scanning the line [line].
_FileReadStatus _updatedStatus(_FileReadStatus oldStatus, String line) {
_FileReadStatus lineStatus;
if (line.trim().startsWith('//')) {
lineStatus = _FileReadStatus.comments;
} else if (line.trim().startsWith('import')) {
lineStatus = _FileReadStatus.imports;
} else {
lineStatus = _FileReadStatus.finished;
}
_FileReadStatus newStatus;
switch (oldStatus) {
case _FileReadStatus.comments:
newStatus =
(line.trim().isEmpty || lineStatus == _FileReadStatus.comments)
? _FileReadStatus.comments
: lineStatus;
break;
case _FileReadStatus.imports:
newStatus = (line.trim().isEmpty || lineStatus == _FileReadStatus.imports)
? _FileReadStatus.imports
: _FileReadStatus.finished;
break;
case _FileReadStatus.finished:
newStatus = oldStatus;
break;
}
return newStatus;
}
Map<String, String> _createSegments(String sourceDirectoryPath) {
List<File> files = Directory(sourceDirectoryPath)
.listSync(recursive: true)
.whereType<File>()
.toList();
Map<String, StringBuffer> subsegments = {};
Map<String, String> subsegmentPrologues = {};
Set<String> appearedSubsegments = Set();
for (final file in files) {
// Process file.
String content = file.readAsStringSync();
List<String> lines = LineSplitter().convert(content);
_FileReadStatus status = _FileReadStatus.comments;
StringBuffer prologue = StringBuffer();
Set<String> activeSubsegments = Set();
for (final line in lines) {
// Update status.
status = _updatedStatus(status, line);
if (status != _FileReadStatus.finished) {
prologue.writeln(line);
}
// Process run commands.
if (line.trim().startsWith(beginSubsegment)) {
String argumentString = line.replaceFirst(beginSubsegment, '').trim();
List<String> arguments =
argumentString.isEmpty ? [] : argumentString.split(RegExp(r'\s+'));
for (final argument in arguments) {
if (activeSubsegments.contains(argument)) {
throw PreformatterException(
'BEGIN $argument is used twice in file ${file.path}');
} else if (appearedSubsegments.contains(argument)) {
throw PreformatterException('BEGIN $argument is used twice');
} else {
activeSubsegments.add(argument);
appearedSubsegments.add(argument);
subsegments[argument] = StringBuffer();
subsegmentPrologues[argument] = prologue.toString();
}
}
} else if (line.trim().startsWith(endSubsegment)) {
String argumentString = line.replaceFirst(endSubsegment, '').trim();
List<String> arguments =
argumentString.isEmpty ? [] : argumentString.split(RegExp(r'\s+'));
if (arguments.isEmpty && activeSubsegments.length == 1) {
arguments.add(activeSubsegments.first);
}
for (final argument in arguments) {
if (activeSubsegments.contains(argument)) {
activeSubsegments.remove(argument);
} else {
throw PreformatterException(
'END $argument is used without a paired BEGIN in ${file.path}');
}
}
} else {
// Simple line.
for (final name in activeSubsegments) {
subsegments[name].writeln(line);
}
}
}
if (activeSubsegments.isNotEmpty) {
throw PreformatterException('File ${file.path} has unpaired BEGIN');
}
}
Map<String, List<TaggedString>> segments = {};
Map<String, String> segmentPrologues = {};
// Sometimes a code segment is made up of subsegments. They are marked by
// names with a "#" symbol in it, such as "bottomSheetDemoModal#1" and
// "bottomSheetDemoModal#2".
// The following code groups the subsegments by order into segments.
subsegments.forEach((key, value) {
String name;
double order;
if (key.contains('#')) {
List<String> parts = key.split('#');
name = parts[0];
order = double.parse(parts[1]);
} else {
name = key;
order = 0;
}
if (!segments.containsKey(name)) {
segments[name] = [];
}
segments[name].add(
TaggedString(
text: value.toString(),
order: order,
),
);
segmentPrologues[name] = subsegmentPrologues[key];
});
segments.forEach((key, value) {
value.sort((ts1, ts2) => (ts1.order - ts2.order).sign.round());
});
Map<String, String> answer = {};
for (final name in segments.keys) {
StringBuffer buffer = StringBuffer();
buffer.write(segmentPrologues[name].trim());
buffer.write('\n\n');
for (final ts in segments[name]) {
buffer.write(ts.text.trim());
buffer.write('\n\n');
}
answer[name] = buffer.toString();
}
return answer;
}
/// A string [text] together with a number [order], for sorting purposes.
/// Used to store different subsegments of a code segment.
/// The [order] of each subsegment is tagged with the code in order to be
/// sorted in the desired order.
class TaggedString {
TaggedString({this.text, this.order});
final String text;
final double order;
}
void _formatSegments(Map<String, String> segments, String targetFilePath) {
File targetFile = File(targetFilePath);
IOSink output = targetFile.openWrite();
output.write(_globalPrologue);
for (final name in segments.keys) {
String code = segments[name];
output.writeln(' static TextSpan $name (BuildContext context) {');
output.writeln(' final CodeStyle codeStyle = CodeStyle.of(context);');
output.writeln(' return TextSpan(children: [');
List<CodeSpan> codeSpans = DartSyntaxPrehighlighter().format(code);
for (final span in codeSpans) {
output.write(' ');
output.write(span.toString());
output.write(',\n');
}
output.write(' ]); }\n');
}
output.write(_globalEpilogue);
output.close();
}
/// Collect code segments, highlight, and write to file.
///
/// [writeSegments] walks through the directory specified by
/// [sourceDirectoryPath] and reads every file in it,
/// collects code segments marked by "// BEGIN <segment_name>" and "// END",
/// highlights them, and writes to the file specified by
/// [targetFilePath].
///
/// The output file is a dart source file with a class "CodeSegments" and
/// static methods of type TextSpan(BuildContext context).
/// Each method generates a widget that displays a segment of code.
///
/// The target file is overwritten.
void writeSegments({String sourceDirectoryPath, String targetFilePath}) {
Map<String, String> segments = _createSegments(sourceDirectoryPath);
_formatSegments(segments, targetFilePath);
}
class PreformatterException implements Exception {
PreformatterException(this.cause);
String cause;
}

@ -0,0 +1,12 @@
name: codeviewer_cli
description: A command-line application to highlight dart source code.
environment:
sdk: '>=2.4.0 <3.0.0'
dependencies:
string_scanner: 1.0.5
dev_dependencies:
pedantic: 1.8.0
test: ^1.5.0

@ -0,0 +1,79 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
.firebase/
.flutter-plugins-dependencies
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Web related
lib/generated_plugin_registrant.dart
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: f5733f7a62ebc7c2ba324a2b410cd81215956b7d
channel: master
project_type: app

@ -0,0 +1,58 @@
ROOT := $(shell git rev-parse --show-toplevel)
FLUTTER := $(shell which flutter)
FLUTTER_BIN_DIR := $(shell dirname $(FLUTTER))
FLUTTER_DIR := $(FLUTTER_BIN_DIR:/bin=)
DART := $(FLUTTER_BIN_DIR)/cache/dart-sdk/bin/dart
.PHONY: analyze
analyze:
$(FLUTTER) analyze
.PHONY: format
format:
$(FLUTTER) format .
.PHONY: test
test:
$(FLUTTER) test
.PHONY: build-web
build-web:
$(FLUTTER) build web
.PHONY: fetch-master
fetch-master:
$(shell git fetch origin master)
.PHONY: master-branch-check
master-branch-check: fetch-master
ifneq ($(shell git rev-parse --abbrev-ref HEAD),master)
$(error Not on master branch, please checkout master)
endif
ifneq ($(shell git rev-parse HEAD),$(shell git rev-parse origin/master))
$(error Your master branch is not up to date with origin/master, please pull before deploying)
endif
.PHONY: deploy
deploy: master-branch-check build-web
cp $(ROOT)/gallery/web/favicon.ico $(ROOT)/gallery/build/web/
firebase deploy
.PHONY: gen-l10n
gen-l10n:
$(DART) $(FLUTTER_DIR)/dev/tools/localization/bin/gen_l10n.dart \
--template-arb-file=intl_en_US.arb \
--output-localization-file=gallery_localizations.dart \
--output-class=GalleryLocalizations
.PHONY: l10n
l10n: gen-l10n format
cd $(ROOT)/l10n_cli/ && $(FLUTTER) pub get
$(DART) $(ROOT)/l10n_cli/bin/main.dart
.PHONY: update-code-segments
update-code-segments:
cd $(ROOT)/codeviewer_cli/ && pub get
$(DART) $(ROOT)/codeviewer_cli/bin/main.dart
$(FLUTTER) format $(ROOT)/gallery/lib/codeviewer/code_segments.dart

@ -0,0 +1,33 @@
include: package:pedantic/analysis_options.1.8.0.yaml
analyzer:
exclude:
- lib/l10n/messages_*.dart
strong-mode:
implicit-casts: false
implicit-dynamic: false
linter:
rules:
- avoid_types_on_closure_parameters
- avoid_void_async
- await_only_futures
- camel_case_types
- cancel_subscriptions
- close_sinks
- constant_identifier_names
- control_flow_in_finally
- empty_statements
- hash_and_equals
- implementation_imports
- non_constant_identifier_names
- package_api_docs
- package_names
- package_prefixed_library_names
- test_types_in_equals
- throw_in_finally
- unnecessary_brace_in_string_interps
- unnecessary_getters_setters
- unnecessary_new
- unnecessary_statements
- directives_ordering

@ -0,0 +1,12 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Visual Studio Code related
.classpath
.project
.settings/

@ -0,0 +1,67 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.gallery"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
}

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gallery">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

@ -0,0 +1,33 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gallery">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="Flutter Gallery"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

@ -0,0 +1,13 @@
package com.example.gallery
import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
}
}

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/backgroundColor" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<color name="backgroundColor">#030303</color>
</resources>

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gallery">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

@ -0,0 +1,31 @@
buildscript {
ext.kotlin_version = '1.2.71'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}

@ -0,0 +1,5 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

@ -0,0 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip

@ -0,0 +1,15 @@
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save