a
46
boss_app2/.gitignore
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
|
||||||
|
# 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/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
.packages
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
/build/
|
||||||
|
|
||||||
|
# Web related
|
||||||
|
lib/generated_plugin_registrant.dart
|
||||||
|
|
||||||
|
# Symbolication related
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Obfuscation related
|
||||||
|
app.*.map.json
|
||||||
|
|
||||||
|
# Android Studio will place build artifacts here
|
||||||
|
/android/app/debug
|
||||||
|
/android/app/profile
|
||||||
|
/android/app/release
|
||||||
10
boss_app2/.metadata
Normal file
@ -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: 73adb1406a9cff796e2203ad16fd285220a6ec97
|
||||||
|
channel: beta
|
||||||
|
|
||||||
|
project_type: app
|
||||||
16
boss_app2/README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# boss_app2
|
||||||
|
|
||||||
|
A new Flutter project.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This project is a starting point for a Flutter application.
|
||||||
|
|
||||||
|
A few resources to get you started if this is your first Flutter project:
|
||||||
|
|
||||||
|
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
|
||||||
|
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
|
||||||
|
|
||||||
|
For help getting started with Flutter, view our
|
||||||
|
[online documentation](https://flutter.dev/docs), which offers tutorials,
|
||||||
|
samples, guidance on mobile development, and a full API reference.
|
||||||
921
boss_app2/analysis_options.yaml
Normal file
@ -0,0 +1,921 @@
|
|||||||
|
##
|
||||||
|
# Lint rules to be used for apps without developer facing API. i.e. command line tools and Flutter applications
|
||||||
|
##
|
||||||
|
analyzer:
|
||||||
|
strong-mode:
|
||||||
|
# Will become the default once non-nullable types land
|
||||||
|
# https://github.com/dart-lang/sdk/issues/31410#issuecomment-510683629
|
||||||
|
implicit-casts: true
|
||||||
|
implicit-dynamic: true
|
||||||
|
errors:
|
||||||
|
# treat missing required parameters as a warning (not a hint)
|
||||||
|
missing_required_param: warning
|
||||||
|
# treat missing returns as a warning (not a hint)
|
||||||
|
missing_return: warning
|
||||||
|
# allow having TODOs in the code
|
||||||
|
todo: info
|
||||||
|
|
||||||
|
# Rules are in the same order (alphabetically) as documented at http://dart-lang.github.io/linter/lints
|
||||||
|
# and https://github.com/dart-lang/linter/blob/master/example/all.yaml
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
# Prevents accidental return type changes which results in a breaking API change.
|
||||||
|
# Enforcing return type makes API changes visible in a diff
|
||||||
|
# pedantic: enabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/always_declare_return_types.html
|
||||||
|
- always_declare_return_types
|
||||||
|
|
||||||
|
# Single line `if`s are fine as recommended in Effective Dart "DO format your code using dartfmt"
|
||||||
|
# pedantic: disabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/always_put_control_body_on_new_line.html
|
||||||
|
# - always_put_control_body_on_new_line
|
||||||
|
|
||||||
|
# Flutter widgets always put a Key as first optional parameter which breaks this rule.
|
||||||
|
# Also violates other orderings like matching the class fields or alphabetically.
|
||||||
|
# pedantic: disabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/always_declare_return_types.html
|
||||||
|
# - always_put_required_named_parameters_first
|
||||||
|
|
||||||
|
# All non nullable named parameters should be and annotated with @required.
|
||||||
|
# This allows API consumers to get warnings via lint rather than a crash a runtime.
|
||||||
|
# Might become obsolete with Non-Nullable types
|
||||||
|
# pedantic: enabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/always_require_non_null_named_parameters.html
|
||||||
|
- always_require_non_null_named_parameters
|
||||||
|
|
||||||
|
# Since dart 2.0 dart is a sound language, specifying types is not required anymore.
|
||||||
|
# `var foo = 10;` is enough information for the compiler to make foo a int.
|
||||||
|
# Violates Effective Dart "AVOID type annotating initialized local variables".
|
||||||
|
# Makes code unnecessarily complex https://github.com/dart-lang/linter/issues/1620
|
||||||
|
# pedantic: disabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/always_specify_types.html
|
||||||
|
# - always_specify_types
|
||||||
|
|
||||||
|
# Protect against unintentionally overriding superclass members
|
||||||
|
# pedantic: enabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/annotate_overrides.html
|
||||||
|
- annotate_overrides
|
||||||
|
|
||||||
|
# All methods should define a return type. dynamic is no exception.
|
||||||
|
# Violates Effective Dart "PREFER annotating with dynamic instead of letting inference fail"
|
||||||
|
# pedantic: disabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_annotating_with_dynamic.html
|
||||||
|
# - avoid_annotating_with_dynamic
|
||||||
|
|
||||||
|
# A leftover from dart1, should be deprecated
|
||||||
|
# pedantic: disabled
|
||||||
|
# - https://github.com/dart-lang/linter/issues/1401
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_as.html
|
||||||
|
# - avoid_as
|
||||||
|
|
||||||
|
# Highlights boolean expressions which can be simplified
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_bool_literals_in_conditional_expressions.html
|
||||||
|
- avoid_bool_literals_in_conditional_expressions
|
||||||
|
|
||||||
|
# There are no strong arguments to enable this rule because it is very strict. Catching anything is useful
|
||||||
|
# and common even if not always the most correct thing to do.
|
||||||
|
# pedantic: disabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_catches_without_on_clauses.html
|
||||||
|
# - avoid_catches_without_on_clauses
|
||||||
|
|
||||||
|
# Errors aren't for catching but to prevent prior to runtime
|
||||||
|
# pedantic: disabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_catching_errors.html
|
||||||
|
- avoid_catching_errors
|
||||||
|
|
||||||
|
# Can usually be replaced with an extension
|
||||||
|
# pedantic: disabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_classes_with_only_static_members.html
|
||||||
|
- avoid_classes_with_only_static_members
|
||||||
|
|
||||||
|
# Never accidentally use dynamic invocations
|
||||||
|
# Dart SDK: unreleased • (Linter vnull)
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_dynamic_calls.html
|
||||||
|
# avoid_dynamic_calls
|
||||||
|
|
||||||
|
# Only useful when targeting JS
|
||||||
|
# pedantic: disabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_double_and_int_checks.html
|
||||||
|
# - avoid_double_and_int_checks
|
||||||
|
|
||||||
|
# Prevents accidental empty else cases. See samples in documentation
|
||||||
|
# pedantic: enabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_empty_else.html
|
||||||
|
- avoid_empty_else
|
||||||
|
|
||||||
|
# It is expected that mutable objects which override hash & equals shouldn't be used as keys for hashmaps.
|
||||||
|
# This one use case doesn't make all hash & equals implementations for mutable classes bad.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_equals_and_hash_code_on_mutable_classes.html
|
||||||
|
# - avoid_equals_and_hash_code_on_mutable_classes
|
||||||
|
|
||||||
|
# Use different quotes instead of escaping
|
||||||
|
# Dart SDK: >= 2.8.0-dev.11.0 • (Linter v0.1.111)
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_escaping_inner_quotes.html
|
||||||
|
- avoid_escaping_inner_quotes
|
||||||
|
|
||||||
|
# Prevents unnecessary allocation of a field
|
||||||
|
# pedantic: disabled
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_field_initializers_in_const_classes.html
|
||||||
|
- avoid_field_initializers_in_const_classes
|
||||||
|
|
||||||
|
# Prevents allocating a lambda and allows return/break/continue control flow statements inside the loop
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_function_literals_in_foreach_calls.html
|
||||||
|
- avoid_function_literals_in_foreach_calls
|
||||||
|
|
||||||
|
# Don't break value types by implementing them
|
||||||
|
# http://dart-lang.github.io/linter/lints/avoid_implementing_value_types.html
|
||||||
|
- avoid_implementing_value_types
|
||||||
|
|
||||||
|
# Removes redundant `= null;`
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_init_to_null.html
|
||||||
|
- avoid_init_to_null
|
||||||
|
|
||||||
|
# Only useful when targeting JS
|
||||||
|
# Warns about too large integers when compiling to JS
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_js_rounded_ints.html
|
||||||
|
# - avoid_js_rounded_ints
|
||||||
|
|
||||||
|
# Null checks aren't required in ==() operators
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_null_checks_in_equality_operators.html
|
||||||
|
- avoid_null_checks_in_equality_operators
|
||||||
|
|
||||||
|
# Good APIs don't use ambiguous boolean parameters. Instead use named parameters
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_positional_boolean_parameters.html
|
||||||
|
- avoid_positional_boolean_parameters
|
||||||
|
|
||||||
|
# Don't call print in production code
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_print.html
|
||||||
|
# - avoid_print
|
||||||
|
|
||||||
|
# Always prefer function references over typedefs.
|
||||||
|
# Jumping twice in code to see the signature of a lambda sucks. This is different from the flutter analysis_options
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_private_typedef_functions.html
|
||||||
|
- avoid_private_typedef_functions
|
||||||
|
|
||||||
|
# Don't explicitly set defaults
|
||||||
|
# Dart SDK: >= 2.8.0-dev.1.0 • (Linter v0.1.107)
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_redundant_argument_values.html
|
||||||
|
- avoid_redundant_argument_values
|
||||||
|
|
||||||
|
# package or relative? Let's end the discussion and use package everywhere.
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_relative_lib_imports.html
|
||||||
|
- avoid_relative_lib_imports
|
||||||
|
|
||||||
|
# Not recommended to break dartdoc but besides that there is no reason to continue with bad naming
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_renaming_method_parameters.html
|
||||||
|
# - avoid_renaming_method_parameters
|
||||||
|
|
||||||
|
# Setters always return void, therefore defining void is redundant
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_return_types_on_setters.html
|
||||||
|
- avoid_return_types_on_setters
|
||||||
|
|
||||||
|
# Especially with Non-Nullable types on the horizon, `int?` is fine.
|
||||||
|
# There are plenty of valid reasons to return null.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_returning_null.html
|
||||||
|
# - avoid_returning_null
|
||||||
|
|
||||||
|
# Don't use `Future?`, therefore never return null instead of a Future.
|
||||||
|
# Will become obsolete one Non-Nullable types land
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_returning_null_for_future.html
|
||||||
|
- avoid_returning_null_for_future
|
||||||
|
|
||||||
|
# Use empty returns, don't show off with you knowledge about dart internals.
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_returning_null_for_void.html
|
||||||
|
- avoid_returning_null_for_void
|
||||||
|
|
||||||
|
# Hinting you forgot about the cascade operator. But too often you did this on purpose.
|
||||||
|
# There are plenty of valid reasons to return this.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_returning_this.html
|
||||||
|
# - avoid_returning_this
|
||||||
|
|
||||||
|
# Prevents logical inconsistencies. It's good practice to define getters for all existing setters.
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_setters_without_getters.html
|
||||||
|
- avoid_setters_without_getters
|
||||||
|
|
||||||
|
# Don't reuse a type parameter when on with the same name already exists in the same scope
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_shadowing_type_parameters.html
|
||||||
|
- avoid_shadowing_type_parameters
|
||||||
|
|
||||||
|
# A single cascade operator can be replaced with a normal method call
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_single_cascade_in_expression_statements.html
|
||||||
|
- avoid_single_cascade_in_expression_statements
|
||||||
|
|
||||||
|
# Might cause frame drops because of synchronous file access on mobile, especially on older phones with slow storage.
|
||||||
|
# There are no known measurements sync access does *not* drop frames.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_slow_async_io.html
|
||||||
|
# - avoid_slow_async_io
|
||||||
|
|
||||||
|
# Don't use .toString() in production code which might be minified
|
||||||
|
# Dart SDK: >= 2.10.0-144.0.dev • (Linter v0.1.119)
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_type_to_string.html
|
||||||
|
- avoid_type_to_string
|
||||||
|
|
||||||
|
# Don't use a parameter names which can be confused with a types (i.e. int, bool, num, ...)
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_types_as_parameter_names.html
|
||||||
|
- avoid_types_as_parameter_names
|
||||||
|
|
||||||
|
# Adding the type is not required, but sometimes improves readability. Therefore removing it doesn't always help
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_types_on_closure_parameters.html
|
||||||
|
# - avoid_types_on_closure_parameters
|
||||||
|
|
||||||
|
# Containers without parameters have no effect and can be removed
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_unnecessary_containers.html
|
||||||
|
- avoid_unnecessary_containers
|
||||||
|
|
||||||
|
# Unused parameters should be removed
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_unused_constructor_parameters.html
|
||||||
|
- avoid_unused_constructor_parameters
|
||||||
|
|
||||||
|
# TODO double check
|
||||||
|
# For async functions use `Future<void>` as return value, not `void`
|
||||||
|
# This allows usage of the await keyword and prevents operations from running in parallel.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_void_async.html
|
||||||
|
- avoid_void_async
|
||||||
|
|
||||||
|
# Flutter mobile only: Web packages aren't available in mobile flutter apps
|
||||||
|
# https://dart-lang.github.io/linter/lints/avoid_web_libraries_in_flutter.html
|
||||||
|
- avoid_web_libraries_in_flutter
|
||||||
|
|
||||||
|
# Use the await keyword only for futures. There is nothing to await in synchronous code
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/await_only_futures.html
|
||||||
|
- await_only_futures
|
||||||
|
|
||||||
|
# Follow the style guide and use UpperCamelCase for extensions
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/camel_case_extensions.html
|
||||||
|
- camel_case_extensions
|
||||||
|
|
||||||
|
# Follow the style guide and use UpperCamelCase for class names and typedefs
|
||||||
|
# https://dart-lang.github.io/linter/lints/camel_case_types.html
|
||||||
|
- camel_case_types
|
||||||
|
|
||||||
|
# Prevents leaks and code executing after their lifecycle.
|
||||||
|
# Discussion https://github.com/passsy/dart-lint/issues/4
|
||||||
|
#
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/cancel_subscriptions.html
|
||||||
|
- cancel_subscriptions
|
||||||
|
|
||||||
|
# The cascade syntax is weird and you shouldn't be forced to use it.
|
||||||
|
# False positives:
|
||||||
|
# https://github.com/dart-lang/linter/issues/1589
|
||||||
|
#
|
||||||
|
# https://dart-lang.github.io/linter/lints/cascade_invocations.html
|
||||||
|
# - cascade_invocations
|
||||||
|
|
||||||
|
# Don't cast T? to T. Use ! instead
|
||||||
|
# Dart SDK: >= 2.11.0-182.0.dev • (Linter v0.1.120)
|
||||||
|
# https://dart-lang.github.io/linter/lints/cast_nullable_to_non_nullable.html
|
||||||
|
- cast_nullable_to_non_nullable
|
||||||
|
|
||||||
|
# False positives, not reliable enough
|
||||||
|
# - https://github.com/dart-lang/linter/issues/1381
|
||||||
|
#
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/close_sinks.html
|
||||||
|
# - close_sinks
|
||||||
|
|
||||||
|
# False positives:
|
||||||
|
# - https://github.com/dart-lang/linter/issues/1142
|
||||||
|
#
|
||||||
|
# https://dart-lang.github.io/linter/lints/comment_references.html
|
||||||
|
# - comment_references
|
||||||
|
|
||||||
|
# Follow standard dart naming style.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/constant_identifier_names.html
|
||||||
|
- constant_identifier_names
|
||||||
|
|
||||||
|
# Prevents hard to debug code
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/control_flow_in_finally.html
|
||||||
|
- control_flow_in_finally
|
||||||
|
|
||||||
|
# Single line `if`s are fine, but when a new line splits the bool expression and body curly braces
|
||||||
|
# are recommended. It prevents the danging else problem and easily allows the addition of more lines inside
|
||||||
|
# the if body
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/curly_braces_in_flow_control_structures.html
|
||||||
|
- curly_braces_in_flow_control_structures
|
||||||
|
|
||||||
|
# Still experimental and pretty much work when enforced
|
||||||
|
# https://dart-lang.github.io/linter/lints/diagnostic_describe_all_properties.html
|
||||||
|
# - diagnostic_describe_all_properties
|
||||||
|
|
||||||
|
# Follows dart style. Fully supported by IDEs and no manual effort for a consistent style
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/directives_ordering.html
|
||||||
|
- directives_ordering
|
||||||
|
|
||||||
|
# String.fromEnvironment looks up env variables at compile time. The variable is baked in by the compiler
|
||||||
|
# and can't be changed by environment variables.
|
||||||
|
#
|
||||||
|
# For dart apps:
|
||||||
|
# Better look up a environment variable at runtime with Platform.environment
|
||||||
|
# or use code generation to define variables at compile time.
|
||||||
|
#
|
||||||
|
# For Flutter apps:
|
||||||
|
# String.fromEnvironment is the recommended way to include variables defined with `flutter build --dart-define`
|
||||||
|
#
|
||||||
|
# pedantic: disabled
|
||||||
|
# Dart SDK: >= 2.10.0-0.0.dev • (Linter v0.1.117)
|
||||||
|
# https://dart-lang.github.io/linter/lints/do_not_use_environment.html
|
||||||
|
# - do_not_use_environment
|
||||||
|
|
||||||
|
# Add a comment why no further error handling is required
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/empty_catches.html
|
||||||
|
- empty_catches
|
||||||
|
|
||||||
|
# Removed empty constructor bodies
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/empty_constructor_bodies.html
|
||||||
|
- empty_constructor_bodies
|
||||||
|
|
||||||
|
# Don't allow empty if bodies. Works together with curly_braces_in_flow_control_structures
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/empty_statements.html
|
||||||
|
- empty_statements
|
||||||
|
|
||||||
|
# Enums aren't powerful enough, now enum like classes get the same linting support
|
||||||
|
# pedantic: disabled
|
||||||
|
# Dart SDK: >= 2.9.0-12.0.dev • (Linter v0.1.116)
|
||||||
|
# https://dart-lang.github.io/linter/lints/exhaustive_cases.html
|
||||||
|
- exhaustive_cases
|
||||||
|
|
||||||
|
# Follow dart file naming schema
|
||||||
|
# https://dart-lang.github.io/linter/lints/file_names.html
|
||||||
|
# - file_names
|
||||||
|
|
||||||
|
# Very flutter specific, not applicable for all projects
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/flutter_style_todos.html
|
||||||
|
# - flutter_style_todos # not all todos require a ticket
|
||||||
|
|
||||||
|
# hashCode and equals need to be consistent. One can't live without another.
|
||||||
|
# https://dart-lang.github.io/linter/lints/hash_and_equals.html
|
||||||
|
- hash_and_equals
|
||||||
|
|
||||||
|
# DON'T import implementation files from another package.
|
||||||
|
# If you need access to some internal code, create an issue
|
||||||
|
# https://dart-lang.github.io/linter/lints/implementation_imports.html
|
||||||
|
- implementation_imports
|
||||||
|
|
||||||
|
# Although there are some false positives, this lint generally catches unnecessary checks
|
||||||
|
# - https://github.com/dart-lang/linter/issues/811
|
||||||
|
#
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/invariant_booleans.html
|
||||||
|
- invariant_booleans
|
||||||
|
|
||||||
|
# Type check for Iterable<T>.contains(other) where other is! T
|
||||||
|
# otherwise contains will always report false. Those errors are usually very hard to catch.
|
||||||
|
# https://dart-lang.github.io/linter/lints/iterable_contains_unrelated_type.html
|
||||||
|
- iterable_contains_unrelated_type
|
||||||
|
|
||||||
|
# Hint to join return and assignment.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/join_return_with_assignment.html
|
||||||
|
- join_return_with_assignment
|
||||||
|
|
||||||
|
# Add leading \n which which makes multiline strings easier to read
|
||||||
|
# Dart SDK: >= 2.8.0-dev.16.0 • (Linter v0.1.113)
|
||||||
|
# https://dart-lang.github.io/linter/lints/leading_newlines_in_multiline_strings.html
|
||||||
|
- leading_newlines_in_multiline_strings
|
||||||
|
|
||||||
|
# Makes sure a library name is a valid dart identifier.
|
||||||
|
# This comes in handy for test files combining multiple tests where the file name can be used as identifier
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# import src/some_test.dart as some_test;
|
||||||
|
#
|
||||||
|
# main() {
|
||||||
|
# some_test.main();
|
||||||
|
# }
|
||||||
|
# ```
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/library_names.html
|
||||||
|
- library_names
|
||||||
|
|
||||||
|
# Follow dart style
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/library_prefixes.html
|
||||||
|
- library_prefixes
|
||||||
|
|
||||||
|
# Nobody wants to manually wrap lines when changing a few words. This rule is too hard to be a "general" rule
|
||||||
|
# https://dart-lang.github.io/linter/lints/lines_longer_than_80_chars.html
|
||||||
|
# - lines_longer_than_80_chars
|
||||||
|
|
||||||
|
# Type check for List<T>.remove(item) where item is! T
|
||||||
|
# The list can't contain item. Those errors are not directly obvious especially when refactoring.
|
||||||
|
# https://dart-lang.github.io/linter/lints/list_remove_unrelated_type.html
|
||||||
|
- list_remove_unrelated_type
|
||||||
|
|
||||||
|
# Good for libraries to prevent unnecessary code paths.
|
||||||
|
# False positives may occur for applications when boolean properties are generated by external programs
|
||||||
|
# producing auto-generated source code
|
||||||
|
#
|
||||||
|
# Known issue: while(true) loops https://github.com/dart-lang/linter/issues/453
|
||||||
|
#
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/literal_only_boolean_expressions.html
|
||||||
|
# - literal_only_boolean_expressions
|
||||||
|
|
||||||
|
# Don't forget the whitespaces at the end
|
||||||
|
# Dart SDK: >= 2.8.0-dev.10.0 • (Linter v0.1.110)
|
||||||
|
# https://dart-lang.github.io/linter/lints/missing_whitespace_between_adjacent_strings.html
|
||||||
|
- missing_whitespace_between_adjacent_strings
|
||||||
|
|
||||||
|
# Concat Strings obviously with `+` inside a list.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/no_adjacent_strings_in_list.html
|
||||||
|
- no_adjacent_strings_in_list
|
||||||
|
|
||||||
|
# Second case is basically dead code which will never be reached.
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/no_duplicate_case_values.html
|
||||||
|
- no_duplicate_case_values
|
||||||
|
|
||||||
|
# Flutter only: `createState` shouldn't pass information into the state
|
||||||
|
# https://dart-lang.github.io/linter/lints/no_logic_in_create_state.html
|
||||||
|
- no_logic_in_create_state
|
||||||
|
|
||||||
|
# calling `runtimeType` may be a performance problem
|
||||||
|
# Dart SDK: >= 2.8.0-dev.10.0 • (Linter v0.1.110)
|
||||||
|
# https://dart-lang.github.io/linter/lints/no_runtimeType_toString.html
|
||||||
|
- no_runtimeType_toString
|
||||||
|
|
||||||
|
# Follow dart style naming conventions
|
||||||
|
# https://dart-lang.github.io/linter/lints/non_constant_identifier_names.html
|
||||||
|
- non_constant_identifier_names
|
||||||
|
|
||||||
|
# Generic T might have a value of String or String?. Both are valid.
|
||||||
|
# This lint triggers when ! is used on T? casting (String?)? to String and not (String?)? to String?
|
||||||
|
# Dart SDK: >= 2.11.0-182.0.dev • (Linter v0.1.120)
|
||||||
|
# https://dart-lang.github.io/linter/lints/null_check_on_nullable_type_parameter.html
|
||||||
|
- null_check_on_nullable_type_parameter
|
||||||
|
|
||||||
|
# Might become irrelevant when non-nullable types land in dart. Until then use this lint check which checks for
|
||||||
|
# non null arguments for specific dart sdk methods.
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/null_closures.html
|
||||||
|
- null_closures
|
||||||
|
|
||||||
|
# Types for local variables may improve readability.
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/omit_local_variable_types.html
|
||||||
|
# - omit_local_variable_types
|
||||||
|
|
||||||
|
# Defining interfaces (abstract classes), with only one method, makes sense architecture wise
|
||||||
|
# Discussion: https://github.com/passsy/dart-lint/issues/2
|
||||||
|
#
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/one_member_abstracts.html
|
||||||
|
# - one_member_abstracts
|
||||||
|
|
||||||
|
# Since Errors aren't intended to be caught (see avoid_catching_errors), throwing anything
|
||||||
|
# doesn't cause trouble.
|
||||||
|
# https://dart-lang.github.io/linter/lints/only_throw_errors.html
|
||||||
|
# - only_throw_errors
|
||||||
|
|
||||||
|
# Highlights unintentionally overridden fields.
|
||||||
|
# https://dart-lang.github.io/linter/lints/overridden_fields.html
|
||||||
|
- overridden_fields
|
||||||
|
|
||||||
|
# Only relevant for packages, not applications or general dart code
|
||||||
|
# https://dart-lang.github.io/linter/lints/package_api_docs.html
|
||||||
|
# - package_api_docs
|
||||||
|
|
||||||
|
# Follow dart style package naming convention
|
||||||
|
# https://dart-lang.github.io/linter/lints/package_names.html
|
||||||
|
- package_names
|
||||||
|
|
||||||
|
# Seems very rare, especially for applications.
|
||||||
|
# https://dart-lang.github.io/linter/lints/package_prefixed_library_names.html
|
||||||
|
- package_prefixed_library_names
|
||||||
|
|
||||||
|
# Most likely a mistake, if not: bad practice
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/parameter_assignments.html
|
||||||
|
- parameter_assignments
|
||||||
|
|
||||||
|
# Is contradictory to `no_adjacent_strings_in_list`
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_adjacent_string_concatenation.html
|
||||||
|
# - prefer_adjacent_string_concatenation
|
||||||
|
|
||||||
|
# Makes it easier to migrate to const constructors and to have final fields
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_asserts_in_initializer_lists.html
|
||||||
|
- prefer_asserts_in_initializer_lists
|
||||||
|
|
||||||
|
# Assertions blocks don't require a message because they throw simple to understand errors
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_asserts_with_message.html
|
||||||
|
# - prefer_asserts_with_message
|
||||||
|
|
||||||
|
# Collection literals are shorter. They exists, use them.
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_collection_literals.html
|
||||||
|
- prefer_collection_literals
|
||||||
|
|
||||||
|
# Use the ??= operator when possible
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_conditional_assignment.html
|
||||||
|
- prefer_conditional_assignment
|
||||||
|
|
||||||
|
# Always use const when possible, make runtime faster
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_const_constructors.html
|
||||||
|
- prefer_const_constructors
|
||||||
|
|
||||||
|
# Add a const constructor when possible
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_const_constructors_in_immutables.html
|
||||||
|
- prefer_const_constructors_in_immutables
|
||||||
|
|
||||||
|
# final is good, const is better
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_const_declarations.html
|
||||||
|
- prefer_const_declarations
|
||||||
|
|
||||||
|
# Always use const when possible, make runtime faster
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_const_literals_to_create_immutables.html
|
||||||
|
- prefer_const_literals_to_create_immutables
|
||||||
|
|
||||||
|
# Dart has named constructors. Static methods in other languages (java) are a workaround which don't have
|
||||||
|
# named constructors.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_constructors_over_static_methods.html
|
||||||
|
- prefer_constructors_over_static_methods
|
||||||
|
|
||||||
|
# Contains may be faster and is easier to read
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_contains.html
|
||||||
|
- prefer_contains
|
||||||
|
|
||||||
|
# Use whatever makes you happy. lint doesn't define a style
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_double_quotes.html
|
||||||
|
# - prefer_double_quotes
|
||||||
|
|
||||||
|
# Prevent confusion with call-side when using named parameters
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_equal_for_default_values.html
|
||||||
|
- prefer_equal_for_default_values
|
||||||
|
|
||||||
|
# Single line methods + implementation makes it hard to write comments for that line.
|
||||||
|
# Dense code isn't necessarily better code.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_expression_function_bodies.html
|
||||||
|
# - prefer_expression_function_bodies
|
||||||
|
|
||||||
|
# Avoid accidental reassignments and allows the compiler to do optimizations.
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_final_fields.html
|
||||||
|
- prefer_final_fields
|
||||||
|
|
||||||
|
# Helps avoid accidental reassignments and allows the compiler to do optimizations.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_final_in_for_each.html
|
||||||
|
- prefer_final_in_for_each
|
||||||
|
|
||||||
|
# Helps avoid accidental reassignments and allows the compiler to do optimizations.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_final_locals.html
|
||||||
|
- prefer_final_locals
|
||||||
|
|
||||||
|
# Saves lot of code
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_for_elements_to_map_fromIterable.html
|
||||||
|
- prefer_for_elements_to_map_fromIterable
|
||||||
|
|
||||||
|
# Dense code isn't necessarily better code
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_foreach.html
|
||||||
|
# - prefer_foreach
|
||||||
|
|
||||||
|
# As Dart allows local function declarations, it is a good practice to use them in the place of function literals.
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_function_declarations_over_variables.html
|
||||||
|
- prefer_function_declarations_over_variables
|
||||||
|
|
||||||
|
# For consistency
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_generic_function_type_aliases.html
|
||||||
|
- prefer_generic_function_type_aliases
|
||||||
|
|
||||||
|
# Allows potential usage of const
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_if_elements_to_conditional_expressions.html
|
||||||
|
- prefer_if_elements_to_conditional_expressions
|
||||||
|
|
||||||
|
# Dart has a special operator for this, use it
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_if_null_operators.html
|
||||||
|
- prefer_if_null_operators
|
||||||
|
|
||||||
|
# Terser code
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_initializing_formals.html
|
||||||
|
- prefer_initializing_formals
|
||||||
|
|
||||||
|
# Easier move towards const, and way easier to read
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_inlined_adds.html
|
||||||
|
- prefer_inlined_adds
|
||||||
|
|
||||||
|
# There is no argument which makes int literals better than double literals for doubles.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_int_literals.html
|
||||||
|
# - prefer_int_literals
|
||||||
|
|
||||||
|
# Interpolate, use less "", '' and +
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_interpolation_to_compose_strings.html
|
||||||
|
- prefer_interpolation_to_compose_strings
|
||||||
|
|
||||||
|
# Iterables do not necessary know their length
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_is_empty.html
|
||||||
|
- prefer_is_empty
|
||||||
|
|
||||||
|
# Easier to read
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_is_not_empty.html
|
||||||
|
- prefer_is_not_empty
|
||||||
|
|
||||||
|
# Use the `foo is! Foo` instead of `!(foo is Foo)`
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_is_not_operator.html
|
||||||
|
- prefer_is_not_operator
|
||||||
|
|
||||||
|
# Easier to read
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_iterable_whereType.html
|
||||||
|
- prefer_iterable_whereType
|
||||||
|
|
||||||
|
# Users of a 3rd party mixins can't change 3rd party code to use the mixin syntax.
|
||||||
|
# This makes the rule useless
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_mixin.html
|
||||||
|
# - prefer_mixin
|
||||||
|
|
||||||
|
# Makes expressions with null checks easier to read.
|
||||||
|
# https://github.com/flutter/flutter/pull/32711#issuecomment-492930932
|
||||||
|
- prefer_null_aware_operators
|
||||||
|
|
||||||
|
# Conflicting with `avoid_relative_lib_imports` which is enforced
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_relative_imports.html
|
||||||
|
# - prefer_relative_imports
|
||||||
|
|
||||||
|
# Use whatever makes you happy. noexcuse doesn't define a style
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_single_quotes.html
|
||||||
|
# - prefer_single_quotes
|
||||||
|
|
||||||
|
# Allows potential usage of const
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_spread_collections.html
|
||||||
|
- prefer_spread_collections
|
||||||
|
|
||||||
|
# Define types
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_typing_uninitialized_variables.html
|
||||||
|
- prefer_typing_uninitialized_variables
|
||||||
|
|
||||||
|
# Null is not a type, use void
|
||||||
|
# https://dart-lang.github.io/linter/lints/prefer_void_to_null.html
|
||||||
|
- prefer_void_to_null
|
||||||
|
|
||||||
|
# Document the replacement API
|
||||||
|
# https://dart-lang.github.io/linter/lints/provide_deprecation_message.html
|
||||||
|
- provide_deprecation_message
|
||||||
|
|
||||||
|
# Definitely not a rule for standard dart code. Maybe relevant for packages
|
||||||
|
# https://dart-lang.github.io/linter/lints/public_member_api_docs.html
|
||||||
|
# - public_member_api_docs
|
||||||
|
|
||||||
|
# Hints accidental recursions
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/recursive_getters.html
|
||||||
|
- recursive_getters
|
||||||
|
|
||||||
|
# Flutter only, prefer SizedBox over Container which offers a const constructors
|
||||||
|
# Dart SDK: >= 2.9.0-4.0.dev • (Linter v0.1.115)
|
||||||
|
# https://dart-lang.github.io/linter/lints/sized_box_for_whitespace.html
|
||||||
|
- sized_box_for_whitespace
|
||||||
|
|
||||||
|
# Follow dart style use triple slashes
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/slash_for_doc_comments.html
|
||||||
|
- slash_for_doc_comments
|
||||||
|
|
||||||
|
# Flutter only, always put child last
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/sort_child_properties_last.html
|
||||||
|
- sort_child_properties_last
|
||||||
|
|
||||||
|
# Working, results in consistent code. But too opinionated
|
||||||
|
# Discussion: https://github.com/passsy/dart-lint/issues/1
|
||||||
|
#
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/sort_constructors_first.html
|
||||||
|
# - sort_constructors_first
|
||||||
|
|
||||||
|
# Any sorting is better than no sorting
|
||||||
|
# https://dart-lang.github.io/linter/lints/sort_pub_dependencies.html
|
||||||
|
# - sort_pub_dependencies
|
||||||
|
|
||||||
|
# Default constructor comes first.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/sort_unnamed_constructors_first.html
|
||||||
|
- sort_unnamed_constructors_first
|
||||||
|
|
||||||
|
# First test, then cast
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/test_types_in_equals.html
|
||||||
|
- test_types_in_equals
|
||||||
|
|
||||||
|
# Hard to debug and bad style
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/throw_in_finally.html
|
||||||
|
- throw_in_finally
|
||||||
|
|
||||||
|
# Help the compiler at compile time with non-null asserts rather than crashing at runtime
|
||||||
|
# Dart SDK: >= 2.11.0-182.0.dev • (Linter v0.1.120)
|
||||||
|
# https://dart-lang.github.io/linter/lints/tighten_type_of_initializing_formals.html
|
||||||
|
- tighten_type_of_initializing_formals
|
||||||
|
|
||||||
|
# Type annotations make the compiler intelligent, use them
|
||||||
|
# https://dart-lang.github.io/linter/lints/type_annotate_public_apis.html
|
||||||
|
- type_annotate_public_apis
|
||||||
|
|
||||||
|
# Don't add types for already typed constructor parameters.
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/type_init_formals.html
|
||||||
|
- type_init_formals
|
||||||
|
|
||||||
|
# Too many false positives.
|
||||||
|
# Using the pedantic package for the unawaited function doesn't make code better readable
|
||||||
|
#
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unawaited_futures.html
|
||||||
|
# - unawaited_futures
|
||||||
|
|
||||||
|
# Remove async/await clutter when not required
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_await_in_return.html
|
||||||
|
- unnecessary_await_in_return
|
||||||
|
|
||||||
|
# Remove unnecessary braces
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_brace_in_string_interps.html
|
||||||
|
- unnecessary_brace_in_string_interps
|
||||||
|
|
||||||
|
# Yes, const everywhere. But not in an already const scope
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_const.html
|
||||||
|
- unnecessary_const
|
||||||
|
|
||||||
|
# Disabled because `final` prevents accidental reassignment
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_final.html
|
||||||
|
# - unnecessary_final
|
||||||
|
|
||||||
|
# Getter/setters can be added later on in a non API breaking manner
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_getters_setters.html
|
||||||
|
- unnecessary_getters_setters
|
||||||
|
|
||||||
|
# Flutter setState is a good example where a lambda should always be used.
|
||||||
|
# https://github.com/dart-lang/linter/issues/498
|
||||||
|
#
|
||||||
|
# Some generic code sometimes requires lambdas, otherwise the generic type isn't forwarded correctly.
|
||||||
|
#
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_lambdas.html
|
||||||
|
# - unnecessary_lambdas
|
||||||
|
|
||||||
|
# Remove the optional `new` keyword
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_new.html
|
||||||
|
- unnecessary_new
|
||||||
|
|
||||||
|
# Don't assign `null` when value is already `null`.
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_null_aware_assignments.html
|
||||||
|
- unnecessary_null_aware_assignments
|
||||||
|
|
||||||
|
# Remove ! when already non-nullable
|
||||||
|
# Dart SDK: >= 2.10.0-144.0.dev • (Linter v0.1.119)
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_null_checks.html
|
||||||
|
- unnecessary_null_checks
|
||||||
|
|
||||||
|
# Don't assign `null` when value is already `null`.
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_null_in_if_null_operators.html
|
||||||
|
- unnecessary_null_in_if_null_operators
|
||||||
|
|
||||||
|
# If a variable doesn't change and is initialized, no need to define it as nullable (NNDB)
|
||||||
|
# Dart SDK: >= 2.10.0-10.0.dev • (Linter v0.1.118)
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_nullable_for_final_variable_declarations.html
|
||||||
|
- unnecessary_nullable_for_final_variable_declarations
|
||||||
|
|
||||||
|
# Remove overrides which simply call super
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_overrides.html
|
||||||
|
- unnecessary_overrides
|
||||||
|
|
||||||
|
# Remove clutter where possible
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_parenthesis.html
|
||||||
|
- unnecessary_parenthesis
|
||||||
|
|
||||||
|
# Use raw string only when needed
|
||||||
|
# Dart SDK: >= 2.8.0-dev.11.0 • (Linter v0.1.111)
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_raw_strings.html
|
||||||
|
- unnecessary_raw_strings
|
||||||
|
|
||||||
|
# Avoid magic overloads of + operators
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_statements.html
|
||||||
|
- unnecessary_statements
|
||||||
|
|
||||||
|
# Remove unnecessary escape characters
|
||||||
|
# Dart SDK: >= 2.8.0-dev.11.0 • (Linter v0.1.111)
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_string_escapes.html
|
||||||
|
- unnecessary_string_escapes
|
||||||
|
|
||||||
|
# Completely unnecessary code, simplify to save a few CPU cycles
|
||||||
|
# Dart SDK: >= 2.8.0-dev.10.0 • (Linter v0.1.110)
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_string_interpolations.html
|
||||||
|
- unnecessary_string_interpolations
|
||||||
|
|
||||||
|
# The variable is clear, remove clutter
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unnecessary_this.html
|
||||||
|
- unnecessary_this
|
||||||
|
|
||||||
|
# Highlights potential bugs where unrelated types are compared with another. (always *not* equal).
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unrelated_type_equality_checks.html
|
||||||
|
- unrelated_type_equality_checks
|
||||||
|
|
||||||
|
# Web only
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/unsafe_html.html
|
||||||
|
- unsafe_html
|
||||||
|
|
||||||
|
# Always use hex syntax Color(0x00000001), never Color(1)
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/use_full_hex_values_for_flutter_colors.html
|
||||||
|
- use_full_hex_values_for_flutter_colors
|
||||||
|
|
||||||
|
# Always use generic function type syntax, don't mix styles
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/use_function_type_syntax_for_parameters.html
|
||||||
|
- use_function_type_syntax_for_parameters
|
||||||
|
|
||||||
|
# Adding a key without using it isn't helpful in applications, only for the Flutter SDK
|
||||||
|
# Dart SDK: >= 2.8.0-dev.1.0 • (Linter v0.1.108)
|
||||||
|
# https://dart-lang.github.io/linter/lints/use_key_in_widget_constructors.html
|
||||||
|
# - use_key_in_widget_constructors
|
||||||
|
|
||||||
|
# Some might argue late is a code smell, this lint is very opinionated. It triggers only for private fields and
|
||||||
|
# therefore might actually cleanup some code.
|
||||||
|
# There is no performance impact either way https://github.com/dart-lang/linter/pull/2189#discussion_r457945301
|
||||||
|
# Dart SDK: >= 2.10.0-10.0.dev • (Linter v0.1.118)
|
||||||
|
# https://dart-lang.github.io/linter/lints/use_late_for_private_fields_and_variables.html
|
||||||
|
- use_late_for_private_fields_and_variables
|
||||||
|
|
||||||
|
# Use rethrow to preserve the original stacktrace.
|
||||||
|
# https://dart.dev/guides/language/effective-dart/usage#do-use-rethrow-to-rethrow-a-caught-exception
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/use_rethrow_when_possible.html
|
||||||
|
- use_rethrow_when_possible
|
||||||
|
|
||||||
|
# Use the setter syntax
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/use_setters_to_change_properties.html
|
||||||
|
- use_setters_to_change_properties
|
||||||
|
|
||||||
|
# In most cases, using a string buffer is preferred for composing strings due to its improved performance.
|
||||||
|
# https://dart-lang.github.io/linter/lints/use_string_buffers.html
|
||||||
|
- use_string_buffers
|
||||||
|
|
||||||
|
# Naming is hard, strict rules don't help
|
||||||
|
# pedantic: disabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/use_to_and_as_if_applicable.html
|
||||||
|
# - use_to_and_as_if_applicable
|
||||||
|
|
||||||
|
# Catches invalid regular expressions.
|
||||||
|
# pedantic: enabled
|
||||||
|
# https://dart-lang.github.io/linter/lints/valid_regexps.html
|
||||||
|
- valid_regexps
|
||||||
|
|
||||||
|
# Don't assign anything to void
|
||||||
|
# https://dart-lang.github.io/linter/lints/void_checks.html
|
||||||
|
- void_checks
|
||||||
13
boss_app2/android/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
gradle-wrapper.jar
|
||||||
|
/.gradle
|
||||||
|
/captures/
|
||||||
|
/gradlew
|
||||||
|
/gradlew.bat
|
||||||
|
/local.properties
|
||||||
|
GeneratedPluginRegistrant.java
|
||||||
|
|
||||||
|
# Remember to never publicly share your keystore.
|
||||||
|
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||||
|
key.properties
|
||||||
|
**/*.keystore
|
||||||
|
**/*.jks
|
||||||
76
boss_app2/android/app/build.gradle
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
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 flutter.compileSdkVersion
|
||||||
|
compileSdkVersion 31
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '1.8'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
|
applicationId "com.example.boss_app2"
|
||||||
|
// minSdkVersion flutter.minSdkVersion
|
||||||
|
minSdkVersion 21
|
||||||
|
// targetSdkVersion flutter.targetSdkVersion
|
||||||
|
targetSdkVersion 31
|
||||||
|
versionCode flutterVersionCode.toInteger()
|
||||||
|
versionName flutterVersionName
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
def flutterMinSdkVersion = localProperties.getProperty('flutter.minSdkVersion')
|
||||||
|
if (flutterMinSdkVersion == null) {
|
||||||
|
flutterMinSdkVersion = flutter.minSdkVersion.toString()
|
||||||
|
}
|
||||||
7
boss_app2/android/app/src/debug/AndroidManifest.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.example.boss_app2">
|
||||||
|
<!-- 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>
|
||||||
34
boss_app2/android/app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.example.boss_app2">
|
||||||
|
<application
|
||||||
|
android:label="boss_app2"
|
||||||
|
android:name="${applicationName}"
|
||||||
|
android:icon="@mipmap/ic_launcher">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTop"
|
||||||
|
android:theme="@style/LaunchTheme"
|
||||||
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
|
android:hardwareAccelerated="true"
|
||||||
|
android:windowSoftInputMode="adjustResize">
|
||||||
|
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||||
|
the Android process has started. This theme is visible to the user
|
||||||
|
while the Flutter UI initializes. After that, this theme continues
|
||||||
|
to determine the Window background behind the Flutter UI. -->
|
||||||
|
<meta-data
|
||||||
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
|
android:resource="@style/NormalTheme"
|
||||||
|
/>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<!-- Don't delete the meta-data below.
|
||||||
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
|
<meta-data
|
||||||
|
android:name="flutterEmbedding"
|
||||||
|
android:value="2" />
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package com.example.boss_app2
|
||||||
|
|
||||||
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
|
class MainActivity: FlutterActivity() {
|
||||||
|
}
|
||||||
@ -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="?android:colorBackground" />
|
||||||
|
|
||||||
|
<!-- You can insert your own image assets here -->
|
||||||
|
<!-- <item>
|
||||||
|
<bitmap
|
||||||
|
android:gravity="center"
|
||||||
|
android:src="@mipmap/launch_image" />
|
||||||
|
</item> -->
|
||||||
|
</layer-list>
|
||||||
BIN
boss_app2/android/app/src/main/res/drawable/app_icon.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
boss_app2/android/app/src/main/res/drawable/app_icon1.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
@ -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="@android:color/white" />
|
||||||
|
|
||||||
|
<!-- You can insert your own image assets here -->
|
||||||
|
<!-- <item>
|
||||||
|
<bitmap
|
||||||
|
android:gravity="center"
|
||||||
|
android:src="@mipmap/launch_image" />
|
||||||
|
</item> -->
|
||||||
|
</layer-list>
|
||||||
BIN
boss_app2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
BIN
boss_app2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
BIN
boss_app2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
BIN
boss_app2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 22 KiB |
18
boss_app2/android/app/src/main/res/values-night/styles.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||||
|
<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>
|
||||||
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
|
This theme determines the color of the Android Window while your
|
||||||
|
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||||
|
running.
|
||||||
|
|
||||||
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
|
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||||
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
18
boss_app2/android/app/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||||
|
<style name="LaunchTheme" parent="@android:style/Theme.Light.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>
|
||||||
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
|
This theme determines the color of the Android Window while your
|
||||||
|
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||||
|
running.
|
||||||
|
|
||||||
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
|
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||||
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
7
boss_app2/android/app/src/profile/AndroidManifest.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.example.boss_app2">
|
||||||
|
<!-- 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>
|
||||||
31
boss_app2/android/build.gradle
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
buildscript {
|
||||||
|
ext.kotlin_version = '1.6.10'
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.buildDir = '../build'
|
||||||
|
subprojects {
|
||||||
|
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||||
|
}
|
||||||
|
subprojects {
|
||||||
|
project.evaluationDependsOn(':app')
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
||||||
3
boss_app2/android/gradle.properties
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
org.gradle.jvmargs=-Xmx1536M
|
||||||
|
android.useAndroidX=true
|
||||||
|
android.enableJetifier=true
|
||||||
6
boss_app2/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -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-6.7-all.zip
|
||||||
11
boss_app2/android/settings.gradle
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
include ':app'
|
||||||
|
|
||||||
|
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
||||||
|
def properties = new Properties()
|
||||||
|
|
||||||
|
assert localPropertiesFile.exists()
|
||||||
|
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
||||||
|
|
||||||
|
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||||
|
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||||
|
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
||||||
BIN
boss_app2/assets/iconnya.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
34
boss_app2/ios/.gitignore
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
**/dgph
|
||||||
|
*.mode1v3
|
||||||
|
*.mode2v3
|
||||||
|
*.moved-aside
|
||||||
|
*.pbxuser
|
||||||
|
*.perspectivev3
|
||||||
|
**/*sync/
|
||||||
|
.sconsign.dblite
|
||||||
|
.tags*
|
||||||
|
**/.vagrant/
|
||||||
|
**/DerivedData/
|
||||||
|
Icon?
|
||||||
|
**/Pods/
|
||||||
|
**/.symlinks/
|
||||||
|
profile
|
||||||
|
xcuserdata
|
||||||
|
**/.generated/
|
||||||
|
Flutter/App.framework
|
||||||
|
Flutter/Flutter.framework
|
||||||
|
Flutter/Flutter.podspec
|
||||||
|
Flutter/Generated.xcconfig
|
||||||
|
Flutter/ephemeral/
|
||||||
|
Flutter/app.flx
|
||||||
|
Flutter/app.zip
|
||||||
|
Flutter/flutter_assets/
|
||||||
|
Flutter/flutter_export_environment.sh
|
||||||
|
ServiceDefinitions.json
|
||||||
|
Runner/GeneratedPluginRegistrant.*
|
||||||
|
|
||||||
|
# Exceptions to above rules.
|
||||||
|
!default.mode1v3
|
||||||
|
!default.mode2v3
|
||||||
|
!default.pbxuser
|
||||||
|
!default.perspectivev3
|
||||||
26
boss_app2/ios/Flutter/AppFrameworkInfo.plist
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>App</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>io.flutter.flutter.app</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>App</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>FMWK</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>9.0</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
1
boss_app2/ios/Flutter/Debug.xcconfig
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "Generated.xcconfig"
|
||||||
1
boss_app2/ios/Flutter/Release.xcconfig
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "Generated.xcconfig"
|
||||||
481
boss_app2/ios/Runner.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 50;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||||
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||||
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||||
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 10;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
name = "Embed Frameworks";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||||
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||||
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
|
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
|
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||||
|
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||||
|
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||||
|
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
|
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
|
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||||
|
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||||
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||||
|
9740EEB31CF90195004384FC /* Generated.xcconfig */,
|
||||||
|
);
|
||||||
|
name = Flutter;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
97C146E51CF9000F007C117D = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
9740EEB11CF90186004384FC /* Flutter */,
|
||||||
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
|
97C146EF1CF9000F007C117D /* Products */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
97C146EF1CF9000F007C117D /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||||
|
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||||
|
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||||
|
97C147021CF9000F007C117D /* Info.plist */,
|
||||||
|
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
|
||||||
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||||
|
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
||||||
|
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
||||||
|
);
|
||||||
|
path = Runner;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
|
buildPhases = (
|
||||||
|
9740EEB61CF901F6004384FC /* Run Script */,
|
||||||
|
97C146EA1CF9000F007C117D /* Sources */,
|
||||||
|
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||||
|
97C146EC1CF9000F007C117D /* Resources */,
|
||||||
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = Runner;
|
||||||
|
productName = Runner;
|
||||||
|
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
97C146E61CF9000F007C117D /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 1300;
|
||||||
|
ORGANIZATIONNAME = "";
|
||||||
|
TargetAttributes = {
|
||||||
|
97C146ED1CF9000F007C117D = {
|
||||||
|
CreatedOnToolsVersion = 7.3.1;
|
||||||
|
LastSwiftMigration = 1100;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||||
|
compatibilityVersion = "Xcode 9.3";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 97C146E51CF9000F007C117D;
|
||||||
|
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
97C146ED1CF9000F007C117D /* Runner */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
||||||
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||||
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||||
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "Thin Binary";
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||||
|
};
|
||||||
|
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "Run Script";
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||||
|
};
|
||||||
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
|
||||||
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
97C146FB1CF9000F007C117D /* Base */,
|
||||||
|
);
|
||||||
|
name = Main.storyboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
97C147001CF9000F007C117D /* Base */,
|
||||||
|
);
|
||||||
|
name = LaunchScreen.storyboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
|
249021D4217E4FDB00AE95B9 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.bossApp2;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
|
97C147031CF9000F007C117D /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
97C147041CF9000F007C117D /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
97C147061CF9000F007C117D /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.bossApp2;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
97C147071CF9000F007C117D /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.bossApp2;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
97C147031CF9000F007C117D /* Debug */,
|
||||||
|
97C147041CF9000F007C117D /* Release */,
|
||||||
|
249021D3217E4FDB00AE95B9 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
97C147061CF9000F007C117D /* Debug */,
|
||||||
|
97C147071CF9000F007C117D /* Release */,
|
||||||
|
249021D4217E4FDB00AE95B9 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
||||||
|
}
|
||||||
7
boss_app2/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>PreviewsEnabled</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1300"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||||
|
BuildableName = "Runner.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||||
|
BuildableName = "Runner.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
|
<Testables>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||||
|
BuildableName = "Runner.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Profile"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||||
|
BuildableName = "Runner.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
7
boss_app2/ios/Runner.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "group:Runner.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>PreviewsEnabled</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
16
boss_app2/ios/Runner/AppDelegate.swift
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import UIKit
|
||||||
|
import Flutter
|
||||||
|
|
||||||
|
@UIApplicationMain
|
||||||
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
|
override func application(
|
||||||
|
_ application: UIApplication,
|
||||||
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||||
|
) -> Bool {
|
||||||
|
GeneratedPluginRegistrant.register(with: self)
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
|
||||||
|
}
|
||||||
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,122 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-20x20@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-20x20@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-29x29@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-29x29@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-29x29@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-40x40@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-40x40@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "60x60",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-60x60@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "60x60",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-60x60@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-20x20@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-20x20@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-29x29@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-29x29@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-40x40@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-40x40@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "76x76",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-76x76@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "76x76",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-76x76@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "83.5x83.5",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "1024x1024",
|
||||||
|
"idiom" : "ios-marketing",
|
||||||
|
"filename" : "Icon-App-1024x1024@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 564 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
23
boss_app2/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "LaunchImage.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "LaunchImage@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "LaunchImage@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
boss_app2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
BIN
boss_app2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
BIN
boss_app2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
5
boss_app2/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Launch Screen Assets
|
||||||
|
|
||||||
|
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
|
||||||
|
|
||||||
|
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
|
||||||
37
boss_app2/ios/Runner/Base.lproj/LaunchScreen.storyboard
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="EHf-IW-A2E">
|
||||||
|
<objects>
|
||||||
|
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||||
|
<layoutGuides>
|
||||||
|
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||||
|
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||||
|
</layoutGuides>
|
||||||
|
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||||
|
</imageView>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||||
|
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="53" y="375"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
<resources>
|
||||||
|
<image name="LaunchImage" width="168" height="185"/>
|
||||||
|
</resources>
|
||||||
|
</document>
|
||||||
26
boss_app2/ios/Runner/Base.lproj/Main.storyboard
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--Flutter View Controller-->
|
||||||
|
<scene sceneID="tne-QT-ifu">
|
||||||
|
<objects>
|
||||||
|
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||||
|
<layoutGuides>
|
||||||
|
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||||
|
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||||
|
</layoutGuides>
|
||||||
|
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
||||||
47
boss_app2/ios/Runner/Info.plist
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>Boss App2</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>boss_app2</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UIMainStoryboardFile</key>
|
||||||
|
<string>Main</string>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
1
boss_app2/ios/Runner/Runner-Bridging-Header.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
#import "GeneratedPluginRegistrant.h"
|
||||||
206
boss_app2/lib/controller/boss_controller.dart
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
// ignore_for_file: non_constant_identifier_names
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:boss_app2/global.dart' as globals;
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
// ignore: unused_import
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
//create class LoginController extends ChangeNotifier
|
||||||
|
class BossController extends ChangeNotifier {
|
||||||
|
//create future string login , parameter is String username and password
|
||||||
|
Future<Map> ambilLaporan(
|
||||||
|
String tanggal, String bulan, String tahun, String filter) async {
|
||||||
|
//create string result
|
||||||
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await http.get(
|
||||||
|
Uri.parse(
|
||||||
|
"${globals.http_to_server}api/ambil_laporan?tanggal=$tanggal&bulan=$bulan&tahun=$tahun&filter=$filter"),
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
final data = jsonDecode(response.body);
|
||||||
|
result = data;
|
||||||
|
} catch (e) {
|
||||||
|
result = {"status": "error", "message": e.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map> ambilLaporanDetail(String no_log) async {
|
||||||
|
//create string result
|
||||||
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await http.get(
|
||||||
|
Uri.parse(
|
||||||
|
"${globals.http_to_server}api/ambil_laporan_detail?no_log=$no_log"),
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
|
||||||
|
final data = jsonDecode(response.body);
|
||||||
|
|
||||||
|
result = data;
|
||||||
|
} catch (e) {
|
||||||
|
result = {"status": "error", "message": e.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map> ambilProdukAll(
|
||||||
|
int pageNumber, String filter, String cekFilter) async {
|
||||||
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await http.get(
|
||||||
|
Uri.parse(
|
||||||
|
"${globals.http_to_server}api/ambil_produk_all?page=$pageNumber&filter=$filter&cekfilter=$cekFilter"),
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
|
||||||
|
final data = jsonDecode(response.body);
|
||||||
|
|
||||||
|
result = data;
|
||||||
|
} catch (e) {
|
||||||
|
result = {"status": "error", "message": e.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map> ambilLaporanProdukDetail(
|
||||||
|
int no_barang, int pageNumber, String filter, String cek_filter) async {
|
||||||
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await http.get(
|
||||||
|
Uri.parse(
|
||||||
|
"${globals.http_to_server}api/ambil_log_produk_detail?no_barang=$no_barang&page=$pageNumber&haha=$cek_filter&filter=$filter"),
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
|
||||||
|
final data = jsonDecode(response.body);
|
||||||
|
result = data;
|
||||||
|
} catch (e) {
|
||||||
|
result = {"status": "error", "message": e.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map> ambilProdukDetail(int no_barang) async {
|
||||||
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await http.get(
|
||||||
|
Uri.parse(
|
||||||
|
"${globals.http_to_server}api/ambil_produk_detail?no_barang=$no_barang"),
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
|
||||||
|
final data = jsonDecode(response.body);
|
||||||
|
|
||||||
|
result = data;
|
||||||
|
} catch (e) {
|
||||||
|
result = {"status": "error", "message": e.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map> ambilLaporanAll(
|
||||||
|
int pageNumber, String filter, String cek_filter) async {
|
||||||
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await http.get(
|
||||||
|
Uri.parse(
|
||||||
|
"${globals.http_to_server}api/ambil_laporan_all?page=$pageNumber&haha=$cek_filter&filter=$filter"),
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
|
||||||
|
final data = jsonDecode(response.body);
|
||||||
|
result = data;
|
||||||
|
} catch (e) {
|
||||||
|
result = {"status": "error", "message": e.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> laporanRead(String no_log) async {
|
||||||
|
final sharedPreference = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
|
// sharedPreference.remove('notif');
|
||||||
|
try {
|
||||||
|
await http.get(
|
||||||
|
Uri.parse("${globals.http_to_server}api/laporan_read?no_log=$no_log"),
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
|
||||||
|
// final data = jsonDecode(response.body);
|
||||||
|
final String? _notif = sharedPreference.getString('notif');
|
||||||
|
if (_notif != null) {
|
||||||
|
final List<dynamic> _notifList = jsonDecode(_notif);
|
||||||
|
_notifList
|
||||||
|
.removeWhere((element) => element.toString() == no_log.toString());
|
||||||
|
|
||||||
|
sharedPreference.setString(
|
||||||
|
'notif', (_notifList.isNotEmpty) ? jsonEncode(_notifList) : "");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// result = {"status": "error", "message": e.toString()};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> laporanReadAll() async {
|
||||||
|
final sharedPreference = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
|
// sharedPreference.remove('notif');
|
||||||
|
try {
|
||||||
|
await http.get(Uri.parse("${globals.http_to_server}api/laporan_read_all"),
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
sharedPreference.remove('notif');
|
||||||
|
} catch (e) {
|
||||||
|
// result = {"status": "error", "message": e.toString()};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
boss_app2/lib/controller/datatables_laporan.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class MyData extends DataTableSource {
|
||||||
|
// Generate some made-up data
|
||||||
|
final List<Map<String, dynamic>> _data = List.generate(
|
||||||
|
200,
|
||||||
|
(index) => {
|
||||||
|
"id": index,
|
||||||
|
"title": "Item $index",
|
||||||
|
"price": Random().nextInt(10000),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isRowCountApproximate => false;
|
||||||
|
@override
|
||||||
|
int get rowCount => _data.length;
|
||||||
|
@override
|
||||||
|
int get selectedRowCount => 0;
|
||||||
|
@override
|
||||||
|
DataRow getRow(int index) {
|
||||||
|
return DataRow(cells: [
|
||||||
|
DataCell(Text(_data[index]['id'].toString())),
|
||||||
|
DataCell(Text(_data[index]["title"])),
|
||||||
|
DataCell(Text(_data[index]["price"].toString())),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
107
boss_app2/lib/controller/login_controller.dart
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:boss_app2/global.dart' as globals;
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
//create class LoginController extends ChangeNotifier
|
||||||
|
class LoginController extends ChangeNotifier {
|
||||||
|
//create future string login , parameter is String username and password
|
||||||
|
Future<String> login(String username, String password) async {
|
||||||
|
late String _returnString;
|
||||||
|
|
||||||
|
try {
|
||||||
|
//create final sharedPreferences
|
||||||
|
final sharedPreferences = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
|
//create http get wih basic auth
|
||||||
|
final response = await http.get(
|
||||||
|
Uri.parse(
|
||||||
|
"${globals.http_to_server}api/login_user?username=$username&password=$password"),
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
final data = jsonDecode(response.body);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
if (data['data']['level'] == '0') {
|
||||||
|
sharedPreferences.setString('level', 'Superadmin');
|
||||||
|
} else if (data['data']['level'] == '1') {
|
||||||
|
sharedPreferences.setString('level', 'Boss');
|
||||||
|
}
|
||||||
|
_returnString = "1";
|
||||||
|
sharedPreferences.setString('data', jsonEncode(data['data']));
|
||||||
|
} else if (response.statusCode == 401) {
|
||||||
|
_returnString = "2";
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_returnString = "3";
|
||||||
|
}
|
||||||
|
|
||||||
|
//return result
|
||||||
|
return _returnString;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> getNotif() async {
|
||||||
|
int result;
|
||||||
|
final sharedPreferences = await SharedPreferences.getInstance();
|
||||||
|
try {
|
||||||
|
final response = await http
|
||||||
|
.get(Uri.parse("${globals.http_to_server}api/cek_datanya"), headers: {
|
||||||
|
"Accept": "application/json",
|
||||||
|
"authorization":
|
||||||
|
"Basic ${base64Encode(utf8.encode("Kicap_karan:bb10c6d9f01ec0cb16726b59e36c2f73"))}",
|
||||||
|
"crossDomain": "true"
|
||||||
|
});
|
||||||
|
final data = jsonDecode(response.body);
|
||||||
|
final List datanya = data['data'];
|
||||||
|
|
||||||
|
final String? _notif = sharedPreferences.getString('notif');
|
||||||
|
List<dynamic> _arrayNotif;
|
||||||
|
if (_notif == null) {
|
||||||
|
_arrayNotif = [];
|
||||||
|
} else {
|
||||||
|
_arrayNotif = jsonDecode(_notif);
|
||||||
|
}
|
||||||
|
|
||||||
|
int jumlah = datanya.length;
|
||||||
|
bool cek = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < datanya.length; i++) {
|
||||||
|
cek = false;
|
||||||
|
for (var j = 0; j < _arrayNotif.length; j++) {
|
||||||
|
if (_arrayNotif[j].toString() == datanya[i]['no_log'].toString()) {
|
||||||
|
jumlah = jumlah - 1;
|
||||||
|
cek = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cek == false) {
|
||||||
|
_arrayNotif.add(int.parse(datanya[i]['no_log']));
|
||||||
|
}
|
||||||
|
cek = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedPreferences.setString('notif', jsonEncode(_arrayNotif));
|
||||||
|
// // if (jumlah > 0) {
|
||||||
|
// // NotificationApi.showNotification(
|
||||||
|
// // title: 'Laporan Baru',
|
||||||
|
// // body: 'Ada $jumlah laporan baru',
|
||||||
|
// // payload: 'Laporan Baru',
|
||||||
|
// // );
|
||||||
|
// // }
|
||||||
|
|
||||||
|
result = jumlah;
|
||||||
|
// result = datanya;
|
||||||
|
} catch (e) {
|
||||||
|
// result = [];
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
98
boss_app2/lib/controller/notification_api.dart
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import 'package:boss_app2/page/login.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
|
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
|
||||||
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
import 'package:timezone/timezone.dart' as tz;
|
||||||
|
// import 'package:timezone/tzdata.dart' as tz;
|
||||||
|
|
||||||
|
// ignore: avoid_classes_with_only_static_members
|
||||||
|
class NotificationApi {
|
||||||
|
// Below is the code for initializing the plugin using var _notificationPlugin
|
||||||
|
static final _notifications = FlutterLocalNotificationsPlugin();
|
||||||
|
static final onNotifications = BehaviorSubject<String?>();
|
||||||
|
|
||||||
|
static Future showNotification({
|
||||||
|
int id = 0,
|
||||||
|
String? title,
|
||||||
|
String? body,
|
||||||
|
String? payload,
|
||||||
|
}) async =>
|
||||||
|
_notifications.show(
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
body,
|
||||||
|
await _notificanDetails(),
|
||||||
|
payload: payload,
|
||||||
|
);
|
||||||
|
|
||||||
|
static Future showScheduleNotification() async =>
|
||||||
|
_notifications.zonedSchedule(
|
||||||
|
0,
|
||||||
|
'Cek Laporan',
|
||||||
|
"Laporan Baru Mungkin Ada, Sila Cek Di Aplikasi",
|
||||||
|
// tz.TZDateTime.from(scheduledDate, tz.local),
|
||||||
|
_scheduleDaily(const Time(18)),
|
||||||
|
await _notificanDetails(),
|
||||||
|
payload: "Laporan Baru Mungkin Ada, Sila Cek Di Aplikasi",
|
||||||
|
androidAllowWhileIdle: true,
|
||||||
|
uiLocalNotificationDateInterpretation:
|
||||||
|
UILocalNotificationDateInterpretation.absoluteTime,
|
||||||
|
matchDateTimeComponents: DateTimeComponents.time,
|
||||||
|
);
|
||||||
|
|
||||||
|
static Future _notificanDetails() async {
|
||||||
|
const AndroidNotificationDetails androidPlatformChannelSpecifics =
|
||||||
|
AndroidNotificationDetails(
|
||||||
|
'your channel id',
|
||||||
|
'your channel name',
|
||||||
|
channelDescription: 'your channel description',
|
||||||
|
importance: Importance.max,
|
||||||
|
// priority: Priority.high,
|
||||||
|
// ticker: 'ticker',
|
||||||
|
);
|
||||||
|
return const NotificationDetails(
|
||||||
|
android: androidPlatformChannelSpecifics,
|
||||||
|
iOS: IOSNotificationDetails(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future init(
|
||||||
|
{bool initScheduled = false, BuildContext? context}) async {
|
||||||
|
const android = AndroidInitializationSettings('app_icon');
|
||||||
|
const iOS = IOSInitializationSettings();
|
||||||
|
const settings = InitializationSettings(android: android, iOS: iOS);
|
||||||
|
|
||||||
|
final details = await _notifications.getNotificationAppLaunchDetails();
|
||||||
|
if (details != null && details.didNotificationLaunchApp) {
|
||||||
|
onNotifications.add(details.payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
await _notifications.initialize(
|
||||||
|
settings,
|
||||||
|
onSelectNotification: (payload) async {
|
||||||
|
Navigator.push(
|
||||||
|
context!,
|
||||||
|
MaterialPageRoute(builder: (context) => Login()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (initScheduled) {
|
||||||
|
final locationName = await FlutterNativeTimezone.getLocalTimezone();
|
||||||
|
tz.setLocalLocation(tz.getLocation(locationName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static tz.TZDateTime _scheduleDaily(Time time) {
|
||||||
|
final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
|
||||||
|
final scheduledDate = tz.TZDateTime(tz.local, now.year, now.month, now.day,
|
||||||
|
time.hour, time.minute, time.second);
|
||||||
|
// if (scheduledDate.isBefore(now)) {
|
||||||
|
// scheduledDate = scheduledDate.add(const Duration(days: 1));
|
||||||
|
// }
|
||||||
|
return scheduledDate.isBefore(now)
|
||||||
|
? scheduledDate.add(const Duration(days: 1))
|
||||||
|
: scheduledDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
boss_app2/lib/global.dart
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
int inidia = 1;
|
||||||
|
// ignore: non_constant_identifier_names
|
||||||
|
String http_to_server = "http://192.168.43.125/ilham/server2/";
|
||||||
45
boss_app2/lib/main.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import 'package:boss_app2/controller/login_controller.dart';
|
||||||
|
// import 'package:boss_app/controller/notification_api.dart';
|
||||||
|
import 'package:boss_app2/page/login.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:timezone/data/latest.dart' as tz;
|
||||||
|
|
||||||
|
import 'controller/boss_controller.dart';
|
||||||
|
|
||||||
|
Future<void> main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
tz.initializeTimeZones();
|
||||||
|
// final locationName = await FlutterNativeTimezone.getLocalTimezone();
|
||||||
|
// tz.setLocalLocation(tz.getLocation(locationName));
|
||||||
|
// tz.initializeTimeZones();
|
||||||
|
|
||||||
|
// NotificationApi().initNotification();
|
||||||
|
runApp(const MyApp());
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyApp extends StatelessWidget {
|
||||||
|
const MyApp({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
// This widget is the root of your application.
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MultiProvider(
|
||||||
|
providers: [
|
||||||
|
ChangeNotifierProvider<LoginController>(
|
||||||
|
create: (BuildContext context) => LoginController()),
|
||||||
|
ChangeNotifierProvider<BossController>(
|
||||||
|
create: (BuildContext context) => BossController()),
|
||||||
|
],
|
||||||
|
child: MaterialApp(
|
||||||
|
title: 'Flutter Demo',
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
theme: ThemeData(
|
||||||
|
primarySwatch: Colors.blue,
|
||||||
|
),
|
||||||
|
home: Login(),
|
||||||
|
// home: const notif,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
74
boss_app2/lib/page/before_login.dart
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// ignore_for_file: avoid_void_async
|
||||||
|
|
||||||
|
// import 'package:boss_app/page/boss/index.dart';
|
||||||
|
// import 'package:boss_app/page/login.dart';
|
||||||
|
// import 'package:boss_app/page/superadmin/index.dart';
|
||||||
|
import 'package:boss_app2/page/boss/index.dart';
|
||||||
|
import 'package:boss_app2/page/login.dart';
|
||||||
|
import 'package:boss_app2/page/superadmin/index.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class BeforeLogin extends StatefulWidget {
|
||||||
|
const BeforeLogin({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_BeforeLoginState createState() => _BeforeLoginState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BeforeLoginState extends State<BeforeLogin> {
|
||||||
|
//shared prefs
|
||||||
|
late SharedPreferences sharedPreferences;
|
||||||
|
int _loading = 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() async {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
sharedPreferences = await SharedPreferences.getInstance();
|
||||||
|
final level = sharedPreferences.getString('level');
|
||||||
|
|
||||||
|
if (level == null) {
|
||||||
|
sharedPreferences.remove('level');
|
||||||
|
sharedPreferences.remove('data');
|
||||||
|
setState(() {
|
||||||
|
_loading = 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (level == 'Superadmin') {
|
||||||
|
setState(() {
|
||||||
|
_loading = 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (level == 'Boss') {
|
||||||
|
setState(() {
|
||||||
|
_loading = 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
late Widget retVal;
|
||||||
|
switch (_loading) {
|
||||||
|
case 0:
|
||||||
|
retVal = Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("Loading"),
|
||||||
|
),
|
||||||
|
body: const Center(child: CircularProgressIndicator()),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
retVal = const SuperadminIndex();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
retVal = BossIndex();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
retVal = Login();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
717
boss_app2/lib/page/boss/homeAdmin.dart
Normal file
@ -0,0 +1,717 @@
|
|||||||
|
// ignore_for_file: unused_element, non_constant_identifier_names
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:boss_app2/controller/boss_controller.dart';
|
||||||
|
import 'package:boss_app2/widgets/ourContainer.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:month_picker_dialog/month_picker_dialog.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class HomeAdmin extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_HomeAdminState createState() => _HomeAdminState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HomeAdminState extends State<HomeAdmin> {
|
||||||
|
int _year = DateTime.now().year.toInt();
|
||||||
|
int _bulan = 0;
|
||||||
|
String _hintTextBulanTahun = '-Pilih Bulan / Tahun Terlebih Dahulu';
|
||||||
|
|
||||||
|
//create string tanggal from today
|
||||||
|
// ignore: prefer_final_fields
|
||||||
|
String _tanggal =
|
||||||
|
'${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day}';
|
||||||
|
// ignore: prefer_final_fields, prefer_interpolation_to_compose_strings
|
||||||
|
String _headerLaporan = "Laporan Tanggal " +
|
||||||
|
DateTime.now().year.toString() +
|
||||||
|
'-' +
|
||||||
|
DateTime.now().month.toString() +
|
||||||
|
'-' +
|
||||||
|
DateTime.now().day.toString();
|
||||||
|
|
||||||
|
//create list map with field waktu, status, dan ket and push 10 random data
|
||||||
|
// List<Map<String, String>> _listLaporan = [];
|
||||||
|
|
||||||
|
late List<Map<String, String>> _laporan;
|
||||||
|
// late List<Map<String, dynamic>> _laporanDetail;
|
||||||
|
int _loadingLaporan = 0;
|
||||||
|
|
||||||
|
// ignore: avoid_void_async
|
||||||
|
void _ambilLaporan(String tanggal, String bulan, String tahun, String filter,
|
||||||
|
BuildContext context) async {
|
||||||
|
final BossController _ambilLaporan =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporan = 0;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
final Map _data =
|
||||||
|
await _ambilLaporan.ambilLaporan(tanggal, bulan, tahun, filter);
|
||||||
|
// Navigator.pop(context);
|
||||||
|
|
||||||
|
if (_data['status'] == 'success') {
|
||||||
|
//loop the _data['data'] and push to _laporan by field waktu, status, dan ket
|
||||||
|
if (_data['data'].length > 0) {
|
||||||
|
_laporan = <Map<String, String>>[];
|
||||||
|
for (int i = 0; i < _data['data'].length; i++) {
|
||||||
|
_laporan.add({
|
||||||
|
'waktu': _data['data'][i]['waktu'].toString(),
|
||||||
|
'status': _data['data'][i]['status'],
|
||||||
|
'ket': _data['data'][i]['ket'].toString(),
|
||||||
|
'no_log': _data['data'][i]['no_log'].toString(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_laporan = _laporan;
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporan = 1;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporan = 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (_data['status'] == 'error') {
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporan = 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporan = 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int _loadingBottomSheet = 0;
|
||||||
|
// ignore: avoid_void_async
|
||||||
|
void _ambilLaporanDetail(String no_log, BuildContext context) async {
|
||||||
|
final BossController _ambilLaporan =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
// ignore: prefer_final_locals
|
||||||
|
Map<String, dynamic> _result = {'data': 0};
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_loadingBottomSheet = 0;
|
||||||
|
|
||||||
|
_bottomSheetModal(context, _result);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map _data = await _ambilLaporan.ambilLaporanDetail(no_log);
|
||||||
|
await _ambilLaporan.laporanRead(no_log);
|
||||||
|
Navigator.pop(context);
|
||||||
|
if (_data['status'] == 'success') {
|
||||||
|
setState(() {
|
||||||
|
_loadingBottomSheet = 1;
|
||||||
|
_bottomSheetModal(context, _data['data'][0]);
|
||||||
|
});
|
||||||
|
} else if (_data['status'] == 'error') {
|
||||||
|
setState(() {
|
||||||
|
_loadingBottomSheet = 2;
|
||||||
|
|
||||||
|
_bottomSheetModal(context, _result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_loadingBottomSheet = 2;
|
||||||
|
_bottomSheetModal(context, _result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> _bottomSheetModal(
|
||||||
|
BuildContext context, Map<String, dynamic> _result) async {
|
||||||
|
return showModalBottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
context: context,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
builder: (context) => SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: (_loadingBottomSheet == 0 || _loadingBottomSheet == 2)
|
||||||
|
? 50
|
||||||
|
: 20,
|
||||||
|
),
|
||||||
|
if (_loadingBottomSheet == 0)
|
||||||
|
const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
)
|
||||||
|
else if (_loadingBottomSheet == 1)
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: (MediaQuery.of(context).size.width -
|
||||||
|
(MediaQuery.of(context).size.width * 0.8)) /
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Detail Laporan',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
_detailLaporan(_result),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
else if (_loadingBottomSheet == 2)
|
||||||
|
const Text(
|
||||||
|
'Koneksi Ke Server Bermasalah, Sila Periksa Jaringan Anda'),
|
||||||
|
if (_loadingBottomSheet == 0 || _loadingBottomSheet == 2)
|
||||||
|
const SizedBox(
|
||||||
|
height: 50,
|
||||||
|
)
|
||||||
|
else if (_loadingBottomSheet == 1)
|
||||||
|
const SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _detailLaporan(Map<String, dynamic> _result) {
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
final Map<String, dynamic> _ket = jsonDecode(_result['ket']);
|
||||||
|
// ignore: prefer_typing_uninitialized_variables
|
||||||
|
var _detail;
|
||||||
|
final formatter = NumberFormat('#,000');
|
||||||
|
|
||||||
|
if (_result['status'] == 'Penjualan Produk') {
|
||||||
|
//create var list map
|
||||||
|
final List<Map<String, dynamic>> _arrayPenjualan = (_ket['ket'] as List)
|
||||||
|
.map((dynamic item) => item as Map<String, dynamic>)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
final _widgetTabel = DataTable(
|
||||||
|
columns: const [
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Kode Barang'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Jumlah'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Harga Jual'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Total'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Stok Sebelumnya'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Stok Terkini'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
rows: _arrayPenjualan
|
||||||
|
.map((Map<String, dynamic> laporan) => DataRow(
|
||||||
|
cells: [
|
||||||
|
DataCell(Text(laporan['kode_barang']!)),
|
||||||
|
DataCell(Text(laporan['jumlah']!.toString())),
|
||||||
|
DataCell(Text("Rp. ${laporan['harga_jual']!}")),
|
||||||
|
DataCell(Text("Rp. ${formatter.format(laporan['total'])}")),
|
||||||
|
DataCell(
|
||||||
|
Text(laporan['jumlah_stok_sebelumnya']!.toString())),
|
||||||
|
DataCell(Text(laporan['jumlah_stok_sekarang']!.toString())),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Total Belanja : Rp. ${_ket['total_belanja']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Pembayaran : Rp. ${_ket['pembayaran']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Kembalian : Rp. ${_ket['baki']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
SingleChildScrollView(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal, child: _widgetTabel),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Edit Detail Produk') {
|
||||||
|
// ignore: prefer_typing_uninitialized_variables
|
||||||
|
var _namanya, _harganya, _fotonya;
|
||||||
|
if (_ket['nama_lama'] != _ket['nama_baru']) {
|
||||||
|
_namanya = Column(
|
||||||
|
children: [
|
||||||
|
Text('Nama : ${_ket['nama_lama']} => ${_ket['nama_baru']}'),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_namanya = const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_ket['harga_lama'] != _ket['harga_baru']) {
|
||||||
|
_harganya = Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Harga : Rp. ${_ket['harga_lama']} => Rp. ${_ket['harga_baru']}'),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_harganya = const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_ket['foto_lama'] != _ket['foto_baru']) {
|
||||||
|
_fotonya = Text('Foto : ${_ket['foto_lama']} => ${_ket['foto_baru']}');
|
||||||
|
} else {
|
||||||
|
_fotonya = const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
_namanya,
|
||||||
|
_harganya,
|
||||||
|
_fotonya,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Penambahan Stok') {
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Penambahan Stok : ${_ket['penambahan_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Pembelian : Rp. ${_ket['harga_pembelian_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Sebelumnya : ${_ket['jumlah_stok_sebelumnya']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Baru : ${_ket['total_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Penambahan Produk Baru') {
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Kode Barang : ${_ket['kode_barang']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Nama Barang : ${_ket['nama']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Jual : Rp. ${_ket['harga_jual']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Pembelian Stok : Rp. ${_ket['pembelian_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Jumlah : ${_ket['jumlah']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_detail = Container();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.85,
|
||||||
|
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey,
|
||||||
|
blurRadius: 10,
|
||||||
|
spreadRadius: 1,
|
||||||
|
offset: Offset(
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text("Waktu : ${_result['waktu']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Status : ${_result['status']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
_detail,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
_ambilLaporan(_tanggal, '', '', '', context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// final DataTableSource _data = MyData();
|
||||||
|
// ignore: prefer_final_fields
|
||||||
|
int _currentSortColumn = 0;
|
||||||
|
bool _isAscending = true;
|
||||||
|
|
||||||
|
// bool _buttonFilter = false;
|
||||||
|
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
final TextEditingController _filterLaporan = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// return Scaffold
|
||||||
|
return Scaffold(
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
OurContainer(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Text(
|
||||||
|
"Form Pilih Bulan / Tahun Laporan",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
TextField(
|
||||||
|
enabled: false,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
isDense: true,
|
||||||
|
hintText: _hintTextBulanTahun,
|
||||||
|
filled: true,
|
||||||
|
fillColor: const Color.fromARGB(255, 247, 247, 247),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
|
||||||
|
//create elevated button
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text('Klik Untuk Pilih Bulan / Tanggal'),
|
||||||
|
onPressed: () {
|
||||||
|
showMonthPicker(
|
||||||
|
context: context,
|
||||||
|
firstDate: DateTime(DateTime.now().year - 1),
|
||||||
|
lastDate: DateTime.now(),
|
||||||
|
initialDate: DateTime.now(),
|
||||||
|
locale: const Locale("id"),
|
||||||
|
).then((date) {
|
||||||
|
// get only month and year on date
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_tanggal = '';
|
||||||
|
_bulan = date!.month;
|
||||||
|
_year = date.year;
|
||||||
|
_hintTextBulanTahun =
|
||||||
|
'Bulan ${_bulan.toString()} / Tahun ${_year.toString()}';
|
||||||
|
_headerLaporan =
|
||||||
|
"Laporan Bulan ${_bulan.toString()} / Tahun ${_year.toString()}";
|
||||||
|
});
|
||||||
|
_ambilLaporan('', _bulan.toString(), _year.toString(),
|
||||||
|
'', context);
|
||||||
|
// _tanggal = date.day.toString();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
OurContainer(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Text(
|
||||||
|
_headerLaporan,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
//create data table with column "Waktu", "Status", "Aksi" and 10 rows
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _filterLaporan,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
isDense: true,
|
||||||
|
hintText: 'Berdasarkan Waktu / Status',
|
||||||
|
filled: true,
|
||||||
|
fillColor:
|
||||||
|
const Color.fromARGB(255, 247, 247, 247),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 20),
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Colors.blue,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_tanggal == '') {
|
||||||
|
_ambilLaporan('', _bulan.toString(),
|
||||||
|
_year.toString(), _filterLaporan.text, context);
|
||||||
|
} else {
|
||||||
|
_ambilLaporan(
|
||||||
|
_tanggal, '', '', _filterLaporan.text, context);
|
||||||
|
}
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
},
|
||||||
|
child: const Text('Filter'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
_tampilkanLaporan()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
// title: const Text('Yakin?'),
|
||||||
|
content: const Text(
|
||||||
|
'Ubah Seluruh Laporan Menjadi Sudah Dibaca?',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final BossController _provider =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await _provider.laporanReadAll();
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(const SnackBar(
|
||||||
|
content: Text("Semua Laporan Diubah Menjadi Terbaca"),
|
||||||
|
));
|
||||||
|
} catch (e) {
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
"Koneksi Ke Server Bermasalah, Sila Periksa Jaringan Anda"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Colors.blue,
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
'Ya',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.sticky_note_2_outlined),
|
||||||
|
),
|
||||||
|
floatingActionButtonLocation: FloatingActionButtonLocation.miniStartFloat,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _tampilkanLaporan() {
|
||||||
|
//create switch case
|
||||||
|
switch (_loadingLaporan) {
|
||||||
|
case 0:
|
||||||
|
return Column(
|
||||||
|
children: const [
|
||||||
|
SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
case 1:
|
||||||
|
// ignore: sized_box_for_whitespace
|
||||||
|
return Container(
|
||||||
|
height: 400,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: DataTable(
|
||||||
|
columns: [
|
||||||
|
DataColumn(
|
||||||
|
label: const Text('Waktu'),
|
||||||
|
onSort: (columnIndex, _) {
|
||||||
|
setState(() {
|
||||||
|
if (_isAscending == false) {
|
||||||
|
_laporan.sort((a, b) {
|
||||||
|
return b['waktu']!.compareTo(a['waktu']!);
|
||||||
|
});
|
||||||
|
_isAscending = true;
|
||||||
|
} else {
|
||||||
|
_isAscending = false;
|
||||||
|
_laporan.sort((a, b) {
|
||||||
|
return a['waktu']!.compareTo(b['waktu']!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: const Text('Status'),
|
||||||
|
onSort: (columnIndex, _) {
|
||||||
|
setState(() {
|
||||||
|
if (_isAscending == false) {
|
||||||
|
_laporan.sort((a, b) {
|
||||||
|
return b['status']!.compareTo(a['status']!);
|
||||||
|
});
|
||||||
|
_isAscending = true;
|
||||||
|
} else {
|
||||||
|
_isAscending = false;
|
||||||
|
_laporan.sort((a, b) {
|
||||||
|
return a['status']!.compareTo(b['status']!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const DataColumn(label: Text('Aksi')),
|
||||||
|
],
|
||||||
|
//rows = _laporan
|
||||||
|
rows: _laporan
|
||||||
|
.map((Map<String, dynamic> laporan) => DataRow(
|
||||||
|
cells: [
|
||||||
|
DataCell(Text(laporan['waktu']!)),
|
||||||
|
DataCell(Text(laporan['status']!)),
|
||||||
|
DataCell(
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.article),
|
||||||
|
color: Colors.blue,
|
||||||
|
onPressed: () {
|
||||||
|
_ambilLaporanDetail(
|
||||||
|
laporan['no_log']!.toString(),
|
||||||
|
context);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
sortColumnIndex: _currentSortColumn,
|
||||||
|
sortAscending: _isAscending,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
return Column(
|
||||||
|
children: const [
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
child: Text('Tidak ada laporan untuk filter ini'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
return Column(
|
||||||
|
children: const [
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
child: Text(
|
||||||
|
'Koneksi ke server gagal, Sila Cek Koneksi Internet Anda'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
77
boss_app2/lib/page/boss/index.dart
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import 'package:boss_app2/page/boss/homeAdmin.dart';
|
||||||
|
import 'package:boss_app2/page/boss/laporanPenuh.dart';
|
||||||
|
import 'package:boss_app2/page/boss/produk.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class BossIndex extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_BossIndexState createState() => _BossIndexState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BossIndexState extends State<BossIndex> {
|
||||||
|
Future<bool> _onWillPop() async {
|
||||||
|
return (await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('Yakin?'),
|
||||||
|
content: const Text('Anda Akan Keluar Dari Aplikasi'),
|
||||||
|
actions: <Widget>[
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(false),
|
||||||
|
child: const Text('Tidak'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(true),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Colors.red,
|
||||||
|
),
|
||||||
|
child: const Text('Ya'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)) ??
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// return Scaffold
|
||||||
|
return WillPopScope(
|
||||||
|
onWillPop: _onWillPop,
|
||||||
|
child: DefaultTabController(
|
||||||
|
length: 3,
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
toolbarHeight: AppBar().preferredSize.height + 8,
|
||||||
|
flexibleSpace: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: const [
|
||||||
|
TabBar(tabs: [
|
||||||
|
Tab(
|
||||||
|
text: 'Home',
|
||||||
|
icon: Icon(Icons.home),
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
text: 'Log Produk',
|
||||||
|
icon: Icon(Icons.filter_vintage_sharp),
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
text: 'Laporan Penuh',
|
||||||
|
icon: Icon(Icons.checklist_rtl_rounded),
|
||||||
|
),
|
||||||
|
])
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: TabBarView(
|
||||||
|
children: [
|
||||||
|
HomeAdmin(),
|
||||||
|
// ProdukAdmin(),
|
||||||
|
ProdukAdmin(),
|
||||||
|
const LaporanPenuh(),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
667
boss_app2/lib/page/boss/laporanPenuh.dart
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:boss_app2/widgets/ourContainer.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../controller/boss_controller.dart';
|
||||||
|
|
||||||
|
class LaporanPenuh extends StatefulWidget {
|
||||||
|
const LaporanPenuh({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_LaporanPenuhState createState() => _LaporanPenuhState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LaporanPenuhState extends State<LaporanPenuh> {
|
||||||
|
late List<Map<String, dynamic>> _laporanAll;
|
||||||
|
int _loadingLaporanAll = 0;
|
||||||
|
late int _pageNumber;
|
||||||
|
int _pageNumberIndex = 1;
|
||||||
|
String _cekFilter = 'tiada';
|
||||||
|
String _filterLaporan = '';
|
||||||
|
final _inputFilterLaporan = TextEditingController();
|
||||||
|
|
||||||
|
// ignore: avoid_void_async
|
||||||
|
void _ambilLaporanAll(BuildContext context, int pageNumber, String filter,
|
||||||
|
String cekFilter) async {
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporanAll = 0;
|
||||||
|
_pageNumberIndex = pageNumber;
|
||||||
|
_cekFilter = cekFilter;
|
||||||
|
_filterLaporan = filter;
|
||||||
|
});
|
||||||
|
_laporanAll = [];
|
||||||
|
final BossController _toController =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map _data =
|
||||||
|
await _toController.ambilLaporanAll(pageNumber, filter, cekFilter);
|
||||||
|
|
||||||
|
if (_data['status'] == 'success') {
|
||||||
|
//loop the _data['data'] and push to _laporan by field waktu, status, dan ket
|
||||||
|
if (_data['data'].length > 0) {
|
||||||
|
_laporanAll = (_data['data'] as List)
|
||||||
|
.map((dynamic item) => item as Map<String, dynamic>)
|
||||||
|
.toList();
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporanAll = 1;
|
||||||
|
_pageNumber = (_data['ceil'] / 10).ceil();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporanAll = 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (_data['status'] == 'error') {
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporanAll = 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporanAll = 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_ambilLaporanAll(context, _pageNumberIndex, _filterLaporan, _cekFilter);
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
OurContainer(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Text(
|
||||||
|
"Filter Laporan",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _inputFilterLaporan,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
isDense: true,
|
||||||
|
hintText: 'Kode / Nama Produk',
|
||||||
|
filled: true,
|
||||||
|
fillColor: const Color.fromARGB(255, 247, 247, 247),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 20),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (_inputFilterLaporan.text == '') {
|
||||||
|
_ambilLaporanAll(
|
||||||
|
context, 1, _filterLaporan, 'tiada');
|
||||||
|
} else {
|
||||||
|
_ambilLaporanAll(
|
||||||
|
context, 1, _inputFilterLaporan.text, 'ada');
|
||||||
|
}
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
},
|
||||||
|
child: const Text('Filter'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
OurContainer(
|
||||||
|
child: (_loadingLaporanAll == 0)
|
||||||
|
? Column(
|
||||||
|
children: const [
|
||||||
|
SizedBox(height: 25),
|
||||||
|
Center(child: CircularProgressIndicator())
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: (_loadingLaporanAll == 2)
|
||||||
|
? Column(
|
||||||
|
children: const [
|
||||||
|
SizedBox(height: 25),
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
'Koneksi Ke Server Bermasalah, Sila Periksa Jaringan Anda'),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: (_loadingLaporanAll == 1)
|
||||||
|
? Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxHeight: 450,
|
||||||
|
),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: DataTable(
|
||||||
|
columns: const [
|
||||||
|
DataColumn(label: Text('No')),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Waktu')),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Status')),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Keterangan')),
|
||||||
|
],
|
||||||
|
rows: _laporanAll.map(
|
||||||
|
(Map<String, dynamic> item) {
|
||||||
|
return DataRow(
|
||||||
|
cells: [
|
||||||
|
// DataCell(Text('${_laporanAll.indexOf(item) + 1}')),
|
||||||
|
DataCell(Text(
|
||||||
|
'${item['no_log']}')),
|
||||||
|
DataCell(Text(
|
||||||
|
'${item['waktu']}')),
|
||||||
|
DataCell(Text(
|
||||||
|
'${item['status']}')),
|
||||||
|
DataCell(IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.article),
|
||||||
|
color: Colors.blue,
|
||||||
|
onPressed: () {
|
||||||
|
_bottomSheetModal(
|
||||||
|
context, item);
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_pageButton(context),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: const SizedBox()),
|
||||||
|
const SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
// title: const Text('Yakin?'),
|
||||||
|
content: const Text(
|
||||||
|
'Ubah Seluruh Laporan Menjadi Sudah Dibaca?',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final BossController _provider =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await _provider.laporanReadAll();
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(const SnackBar(
|
||||||
|
content: Text("Semua Laporan Diubah Menjadi Terbaca"),
|
||||||
|
));
|
||||||
|
} catch (e) {
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
"Koneksi Ke Server Bermasalah, Sila Periksa Jaringan Anda"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Colors.blue,
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
'Ya',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.sticky_note_2_outlined),
|
||||||
|
),
|
||||||
|
floatingActionButtonLocation: FloatingActionButtonLocation.miniStartFloat,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleChildScrollView _pageButton(BuildContext context) {
|
||||||
|
final List<Widget> _pageButton = <Widget>[];
|
||||||
|
|
||||||
|
if (_loadingLaporanAll == 1) {
|
||||||
|
if (_pageNumber >= 1 && _pageNumber <= 3) {
|
||||||
|
for (int i = 1; i <= _pageNumber; i++) {
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: (_pageNumberIndex == 1 && i == 1)
|
||||||
|
? Colors.grey
|
||||||
|
: (_pageNumberIndex == 2 && i == 2)
|
||||||
|
? Colors.grey
|
||||||
|
: (_pageNumberIndex == 3 && i == 3)
|
||||||
|
? Colors.grey
|
||||||
|
: Colors.blue,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_pageNumberIndex == 1 && i == 1) {
|
||||||
|
} else if (_pageNumberIndex == 2 && i == 2) {
|
||||||
|
} else if (_pageNumberIndex == 3 && i == 3) {
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_pageNumberIndex = i;
|
||||||
|
// _pageNumber = i;
|
||||||
|
});
|
||||||
|
_ambilLaporanAll(context, i, _filterLaporan, _cekFilter);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text(i.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (_pageNumber > 3) {
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: (_pageNumberIndex != 1) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilLaporanAll(
|
||||||
|
context, _pageNumberIndex - 1, _filterLaporan, _cekFilter);
|
||||||
|
},
|
||||||
|
child: const Text('<'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: (_pageNumberIndex != 1) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilLaporanAll(context, 1, _filterLaporan, _cekFilter);
|
||||||
|
},
|
||||||
|
child: const Text('1'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
const Text('...'),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (_pageNumberIndex != 1 && _pageNumberIndex != _pageNumber) {
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {},
|
||||||
|
child: Text(_pageNumberIndex.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
const Text('...'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary:
|
||||||
|
(_pageNumberIndex != _pageNumber) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilLaporanAll(
|
||||||
|
context, _pageNumber, _filterLaporan, _cekFilter);
|
||||||
|
},
|
||||||
|
child: Text(_pageNumber.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary:
|
||||||
|
(_pageNumberIndex != _pageNumber) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilLaporanAll(
|
||||||
|
context, _pageNumberIndex + 1, _filterLaporan, _cekFilter);
|
||||||
|
},
|
||||||
|
child: const Text('>'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_pageButton.add(const SizedBox());
|
||||||
|
}
|
||||||
|
|
||||||
|
return SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: _pageButton,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore: avoid_void_async
|
||||||
|
void _bottomSheetModal(
|
||||||
|
BuildContext context, Map<String, dynamic> _result) async {
|
||||||
|
final BossController _provider =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await _provider.laporanRead(_result['no_log'].toString());
|
||||||
|
} catch (e) {
|
||||||
|
// print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return showModalBottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
context: context,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
builder: (context) => SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: (MediaQuery.of(context).size.width -
|
||||||
|
(MediaQuery.of(context).size.width * 0.8)) /
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Detail Laporan',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
_detailLaporan(_result),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _detailLaporan(Map<String, dynamic> _result) {
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
final Map<String, dynamic> _ket = jsonDecode(_result['ket']);
|
||||||
|
// ignore: prefer_typing_uninitialized_variables
|
||||||
|
var _detail;
|
||||||
|
final formatter = NumberFormat('#,000');
|
||||||
|
|
||||||
|
if (_result['status'] == 'Penjualan Produk') {
|
||||||
|
//create var list map
|
||||||
|
final List<Map<String, dynamic>> _arrayPenjualan = (_ket['ket'] as List)
|
||||||
|
.map((dynamic item) => item as Map<String, dynamic>)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
final _widgetTabel = DataTable(
|
||||||
|
columns: const [
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Kode Barang'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Jumlah'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Harga Jual'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Total'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Stok Sebelumnya'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Stok Terkini'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
rows: _arrayPenjualan
|
||||||
|
.map((Map<String, dynamic> laporan) => DataRow(
|
||||||
|
cells: [
|
||||||
|
DataCell(Text(laporan['kode_barang']!)),
|
||||||
|
DataCell(Text(laporan['jumlah']!.toString())),
|
||||||
|
DataCell(Text("Rp. ${laporan['harga_jual']!}")),
|
||||||
|
DataCell(Text("Rp. ${formatter.format(laporan['total'])}")),
|
||||||
|
DataCell(
|
||||||
|
Text(laporan['jumlah_stok_sebelumnya']!.toString())),
|
||||||
|
DataCell(Text(laporan['jumlah_stok_sekarang']!.toString())),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Total Belanja : Rp. ${_ket['total_belanja']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Pembayaran : Rp. ${_ket['pembayaran']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Kembalian : Rp. ${_ket['baki']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
SingleChildScrollView(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal, child: _widgetTabel),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Edit Detail Produk') {
|
||||||
|
// ignore: prefer_typing_uninitialized_variables
|
||||||
|
var _namanya, _harganya, _fotonya;
|
||||||
|
if (_ket['nama_lama'] != _ket['nama_baru']) {
|
||||||
|
_namanya = Column(
|
||||||
|
children: [
|
||||||
|
Text('Nama : ${_ket['nama_lama']} => ${_ket['nama_baru']}'),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_namanya = const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_ket['harga_lama'] != _ket['harga_baru']) {
|
||||||
|
_harganya = Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Harga : Rp. ${_ket['harga_lama']} => Rp. ${_ket['harga_baru']}'),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_harganya = const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_ket['foto_lama'] != _ket['foto_baru']) {
|
||||||
|
_fotonya = Text('Foto : ${_ket['foto_lama']} => ${_ket['foto_baru']}');
|
||||||
|
} else {
|
||||||
|
_fotonya = const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
_namanya,
|
||||||
|
_harganya,
|
||||||
|
_fotonya,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Penambahan Stok') {
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Penambahan Stok : ${_ket['penambahan_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Pembelian : Rp. ${_ket['harga_pembelian_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Sebelumnya : ${_ket['jumlah_stok_sebelumnya']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Baru : ${_ket['total_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Penambahan Produk Baru') {
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Kode Barang : ${_ket['kode_barang']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Nama Barang : ${_ket['nama']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Jual : Rp. ${_ket['harga_jual']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Pembelian Stok : Rp. ${_ket['pembelian_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Jumlah : ${_ket['jumlah']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Penjualan Barang Spesifik') {
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Jumlah Pembelian : ${_ket['jumlah_pembelian']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Jual : Rp. ${_ket['harga_jual']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Sebelumnya : ${_ket['stok_sebelumnya']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Terbaru : ${_ket['stok_sekarang']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_detail = Container();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.85,
|
||||||
|
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey,
|
||||||
|
blurRadius: 10,
|
||||||
|
spreadRadius: 1,
|
||||||
|
offset: Offset(
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text("Waktu : ${_result['waktu']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"Status : ${(_result['status'] == 'Penjualan Barang Spesifik') ? 'Penjualan' : _result['status'].toString()}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
_detail,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
440
boss_app2/lib/page/boss/produk.dart
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
import 'package:boss_app2/controller/boss_controller.dart';
|
||||||
|
import 'package:boss_app2/global.dart' as globals;
|
||||||
|
import 'package:boss_app2/page/boss/produkDetail.dart';
|
||||||
|
import 'package:boss_app2/widgets/ourContainer.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class ProdukAdmin extends StatefulWidget {
|
||||||
|
// const ProdukAdmin({Key? key}) : super(key: key);
|
||||||
|
@override
|
||||||
|
_ProdukAdminState createState() => _ProdukAdminState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ProdukAdminState extends State<ProdukAdmin> {
|
||||||
|
late List<Map<String, dynamic>> _produkAll;
|
||||||
|
int _loadingProdukAll = 0;
|
||||||
|
late int _pageNumber;
|
||||||
|
int _pageNumberIndex = 1;
|
||||||
|
String _cekFilter = 'tiada';
|
||||||
|
|
||||||
|
// ignore: avoid_void_async
|
||||||
|
void _ambilProdukAll(BuildContext context, int pageNumber, String filter,
|
||||||
|
String cekFilter) async {
|
||||||
|
setState(() {
|
||||||
|
_loadingProdukAll = 0;
|
||||||
|
_pageNumberIndex = pageNumber;
|
||||||
|
_cekFilter = cekFilter;
|
||||||
|
});
|
||||||
|
_produkAll = [];
|
||||||
|
final BossController _toController =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map _data =
|
||||||
|
await _toController.ambilProdukAll(pageNumber, filter, cekFilter);
|
||||||
|
|
||||||
|
if (_data['status'] == 'success') {
|
||||||
|
//loop the _data['data'] and push to _laporan by field waktu, status, dan ket
|
||||||
|
if (_data['data'].length > 0) {
|
||||||
|
_produkAll = (_data['data'] as List)
|
||||||
|
.map((dynamic item) => item as Map<String, dynamic>)
|
||||||
|
.toList();
|
||||||
|
setState(() {
|
||||||
|
_loadingProdukAll = 1;
|
||||||
|
_pageNumber = (_data['ceil'] / 10).ceil();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_loadingProdukAll = 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (_data['status'] == 'error') {
|
||||||
|
setState(() {
|
||||||
|
_loadingProdukAll = 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_loadingProdukAll = 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
_ambilProdukAll(context, 1, '', _cekFilter);
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
final TextEditingController _filterProduk = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
OurContainer(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Text(
|
||||||
|
"Filter Produk",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _filterProduk,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
isDense: true,
|
||||||
|
hintText: 'Kode / Nama Produk',
|
||||||
|
filled: true,
|
||||||
|
fillColor: const Color.fromARGB(255, 247, 247, 247),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 20),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
if (_filterProduk.text == '') {
|
||||||
|
_ambilProdukAll(context, 1, '', 'tiada');
|
||||||
|
} else {
|
||||||
|
_ambilProdukAll(
|
||||||
|
context, 1, _filterProduk.text, 'ada');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Cari'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
if (_loadingProdukAll == 0)
|
||||||
|
const Center(child: CircularProgressIndicator())
|
||||||
|
else if (_loadingProdukAll == 1)
|
||||||
|
SizedBox(
|
||||||
|
height: 400,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
DataTable(
|
||||||
|
columns: const [
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Kode'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Nama'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Harga'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Stok'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Laporan'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
rows: _produkAll
|
||||||
|
.map((Map<String, dynamic> item) => DataRow(
|
||||||
|
cells: [
|
||||||
|
DataCell(
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(item['kode_barang']
|
||||||
|
.toString()),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => _tampilkanFoto(
|
||||||
|
context,
|
||||||
|
item['no_barang'],
|
||||||
|
item['foto']),
|
||||||
|
child: Hero(
|
||||||
|
tag:
|
||||||
|
"image${item['no_barang']}",
|
||||||
|
child: CircleAvatar(
|
||||||
|
radius: 15,
|
||||||
|
backgroundImage:
|
||||||
|
NetworkImage(
|
||||||
|
"${globals.http_to_server}img/${item['no_barang']}/${item['foto']}",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DataCell(
|
||||||
|
Text(item['nama'].toString()),
|
||||||
|
),
|
||||||
|
DataCell(
|
||||||
|
Text("Rp. ${item['harga_jual']}"),
|
||||||
|
),
|
||||||
|
DataCell(
|
||||||
|
Text(item['jumlah'].toString()),
|
||||||
|
),
|
||||||
|
DataCell(IconButton(
|
||||||
|
icon: const Icon(Icons.article),
|
||||||
|
color: Colors.blue,
|
||||||
|
onPressed: () {
|
||||||
|
// _ambilLaporanProduk(
|
||||||
|
// context,
|
||||||
|
// int.parse(
|
||||||
|
// item['no_barang']),
|
||||||
|
// 1,
|
||||||
|
// item);
|
||||||
|
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) =>
|
||||||
|
ProdukDetail(
|
||||||
|
no_log: int.parse(
|
||||||
|
item['no_barang']),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
_pageButton(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else if (_loadingProdukAll == 2)
|
||||||
|
const Text(
|
||||||
|
'Tidak ada data',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
)
|
||||||
|
else if (_loadingProdukAll == 3)
|
||||||
|
const Text(
|
||||||
|
'Koneksi Ke Server Bermasalah, Sila Periksa Jaringan Anda',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
// title: const Text('Yakin?'),
|
||||||
|
content: const Text(
|
||||||
|
'Ubah Seluruh Laporan Menjadi Sudah Dibaca?',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final BossController _provider =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await _provider.laporanReadAll();
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(const SnackBar(
|
||||||
|
content: Text("Semua Laporan Diubah Menjadi Terbaca"),
|
||||||
|
));
|
||||||
|
} catch (e) {
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
"Koneksi Ke Server Bermasalah, Sila Periksa Jaringan Anda"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Colors.blue,
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
'Ya',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.sticky_note_2_outlined),
|
||||||
|
),
|
||||||
|
floatingActionButtonLocation: FloatingActionButtonLocation.miniStartFloat,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> _tampilkanFoto(
|
||||||
|
BuildContext context, String item, String foto) {
|
||||||
|
return showModalBottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
context: context,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
builder: (context) => SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Hero(
|
||||||
|
tag: 'image$item',
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
child: Image.network(
|
||||||
|
"${globals.http_to_server}img/$item/$foto",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Row _pageButton() {
|
||||||
|
final List<Widget> _pageButton = <Widget>[];
|
||||||
|
|
||||||
|
if (_loadingProdukAll == 1) {
|
||||||
|
if (_pageNumber >= 1 && _pageNumber <= 3) {
|
||||||
|
for (int i = 1; i <= _pageNumber; i++) {
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: (_pageNumberIndex == 1 && i == 1)
|
||||||
|
? Colors.grey
|
||||||
|
: (_pageNumberIndex == 2 && i == 2)
|
||||||
|
? Colors.grey
|
||||||
|
: (_pageNumberIndex == 3 && i == 3)
|
||||||
|
? Colors.grey
|
||||||
|
: Colors.blue,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_pageNumberIndex == 1 && i == 1) {
|
||||||
|
// ignore: unnecessary_statements
|
||||||
|
null;
|
||||||
|
} else if (_pageNumberIndex == 2 && i == 2) {
|
||||||
|
// ignore: unnecessary_statements
|
||||||
|
null;
|
||||||
|
} else if (_pageNumberIndex == 3 && i == 3) {
|
||||||
|
// ignore: unnecessary_statements
|
||||||
|
null;
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_pageNumberIndex = i;
|
||||||
|
// _pageNumber = i;
|
||||||
|
});
|
||||||
|
_ambilProdukAll(context, i, '', _cekFilter);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text(i.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (_pageNumber > 3) {
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: (_pageNumberIndex != 1) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilProdukAll(context, _pageNumberIndex - 1, '', _cekFilter);
|
||||||
|
},
|
||||||
|
child: const Text('<'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: (_pageNumberIndex != 1) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilProdukAll(context, 1, '', _cekFilter);
|
||||||
|
},
|
||||||
|
child: const Text('1'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
const Text('...'),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (_pageNumberIndex != 1 && _pageNumberIndex != _pageNumber) {
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {},
|
||||||
|
child: Text(_pageNumberIndex.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
const Text('...'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary:
|
||||||
|
(_pageNumberIndex != _pageNumber) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilProdukAll(context, _pageNumber, '', _cekFilter);
|
||||||
|
},
|
||||||
|
child: Text(_pageNumber.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary:
|
||||||
|
(_pageNumberIndex != _pageNumber) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilProdukAll(context, _pageNumberIndex + 1, '', _cekFilter);
|
||||||
|
},
|
||||||
|
child: const Text('>'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_pageButton.add(const SizedBox());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: _pageButton,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
610
boss_app2/lib/page/boss/produkDetail.dart
Normal file
@ -0,0 +1,610 @@
|
|||||||
|
// ignore_for_file: unnecessary_statements
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:boss_app2/widgets/ourContainer.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../controller/boss_controller.dart';
|
||||||
|
|
||||||
|
class ProdukDetail extends StatefulWidget {
|
||||||
|
// ignore: non_constant_identifier_names
|
||||||
|
final int no_log;
|
||||||
|
// ignore: non_constant_identifier_names
|
||||||
|
const ProdukDetail({Key? key, required this.no_log}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ProdukDetailState createState() => _ProdukDetailState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ProdukDetailState extends State<ProdukDetail> {
|
||||||
|
late Map<String, dynamic> _dataProduk;
|
||||||
|
int _loadingProduk = 0;
|
||||||
|
|
||||||
|
// ignore: avoid_void_async
|
||||||
|
void _ambilProdukDetail(BuildContext context, int noBarang) async {
|
||||||
|
setState(() {
|
||||||
|
_loadingProduk = 0;
|
||||||
|
});
|
||||||
|
final BossController _toController =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map _data = await _toController.ambilProdukDetail(noBarang);
|
||||||
|
setState(() {
|
||||||
|
_dataProduk = _data['data'];
|
||||||
|
_loadingProduk = 1;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_loadingProduk = 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
late List<Map<String, dynamic>> _laporanProduk;
|
||||||
|
int _loadingLaporan = 0;
|
||||||
|
late int _pageNumberLaporan;
|
||||||
|
int _pageNumberLaporanIndex = 1;
|
||||||
|
String _filterLaporan = "";
|
||||||
|
String _cekFilter = "tiada";
|
||||||
|
bool _cekLengthData = false;
|
||||||
|
|
||||||
|
// ignore: avoid_void_async
|
||||||
|
void _ambilLogLaporan(BuildContext context, int noBarang, int pageNumber,
|
||||||
|
String filter, String cekFilter) async {
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporan = 0;
|
||||||
|
_pageNumberLaporanIndex = pageNumber;
|
||||||
|
_cekFilter = cekFilter;
|
||||||
|
_filterLaporan = filter;
|
||||||
|
});
|
||||||
|
_laporanProduk = [];
|
||||||
|
final BossController _toController =
|
||||||
|
Provider.of<BossController>(context, listen: false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map _data = await _toController.ambilLaporanProdukDetail(
|
||||||
|
noBarang, pageNumber, filter, cekFilter);
|
||||||
|
_laporanProduk = (_data['data'] as List)
|
||||||
|
.map((dynamic item) => item as Map<String, dynamic>)
|
||||||
|
.toList();
|
||||||
|
setState(() {
|
||||||
|
if (_laporanProduk.isEmpty) {
|
||||||
|
_cekLengthData = false;
|
||||||
|
} else {
|
||||||
|
_cekLengthData = true;
|
||||||
|
}
|
||||||
|
_laporanProduk = _laporanProduk;
|
||||||
|
_loadingLaporan = 1;
|
||||||
|
_pageNumberLaporan = (_data['ceil'] / 10).ceil();
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_loadingLaporan = 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final TextEditingController _inputFilterLaporan = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_ambilLogLaporan(context, widget.no_log, 1, _filterLaporan, _cekFilter);
|
||||||
|
_ambilProdukDetail(context, widget.no_log);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Detail Produk'),
|
||||||
|
),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
OurContainer(
|
||||||
|
child: (_loadingProduk == 1)
|
||||||
|
? Center(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text('Kode : ${_dataProduk['kode_barang']}'),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text('Nama : ${_dataProduk['nama']}'),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text('Harga Jual : ${_dataProduk['harga_jual']}'),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text('Stok : ${_dataProduk['jumlah']}'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: (_loadingProduk == 0)
|
||||||
|
? const Center(child: CircularProgressIndicator())
|
||||||
|
: (_loadingProduk == 2)
|
||||||
|
? const Center(
|
||||||
|
child: Text(
|
||||||
|
'Koneksi Ke Server Bermasalah, Sila Periksa Jaringan Anda'))
|
||||||
|
: Container(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
OurContainer(
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
if (_loadingLaporan == 1)
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _inputFilterLaporan,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
isDense: true,
|
||||||
|
hintText: 'Berdasarkan Waktu / Status',
|
||||||
|
filled: true,
|
||||||
|
fillColor: const Color.fromARGB(
|
||||||
|
255, 247, 247, 247),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 20),
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Colors.blue,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_inputFilterLaporan.text == '') {
|
||||||
|
_ambilLogLaporan(context, widget.no_log, 1,
|
||||||
|
_inputFilterLaporan.text, 'tiada');
|
||||||
|
} else {
|
||||||
|
_ambilLogLaporan(context, widget.no_log, 1,
|
||||||
|
_inputFilterLaporan.text, 'ada');
|
||||||
|
}
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
child: const Text('Filter'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (_cekLengthData)
|
||||||
|
SingleChildScrollView(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: DataTable(
|
||||||
|
columns: const [
|
||||||
|
DataColumn(
|
||||||
|
label: Text('No'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Waktu'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Status'),
|
||||||
|
),
|
||||||
|
DataColumn(
|
||||||
|
label: Text('Keterangan'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
rows: _laporanProduk
|
||||||
|
.map(
|
||||||
|
(dynamic item) => DataRow(
|
||||||
|
cells: [
|
||||||
|
DataCell(
|
||||||
|
Text(
|
||||||
|
item['no_log'].toString(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DataCell(
|
||||||
|
Text(
|
||||||
|
item['waktu'].toString(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DataCell(
|
||||||
|
(item['status'] !=
|
||||||
|
"Penjualan Barang Spesifik")
|
||||||
|
? Text(
|
||||||
|
item['status'].toString(),
|
||||||
|
)
|
||||||
|
: const Text("Penjualan"),
|
||||||
|
),
|
||||||
|
DataCell(IconButton(
|
||||||
|
icon: const Icon(Icons.article),
|
||||||
|
color: Colors.blue,
|
||||||
|
onPressed: () {
|
||||||
|
_bottomSheetModal(
|
||||||
|
context, item);
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
'Tidak Ada Rekod Laporan Untuk Filter "${_inputFilterLaporan.text}"',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
else
|
||||||
|
(_loadingLaporan == 0)
|
||||||
|
? const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
)
|
||||||
|
: (_loadingLaporan == 2)
|
||||||
|
? const Center(
|
||||||
|
child: Text(
|
||||||
|
'Koneksi Ke Serverl Bermasalah, Sila Periksa Jaringan Anda',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
_pageButton(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore: avoid_void_async
|
||||||
|
void _bottomSheetModal(
|
||||||
|
BuildContext context, Map<String, dynamic> _result) async {
|
||||||
|
return showModalBottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
context: context,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
builder: (context) => SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: (MediaQuery.of(context).size.width -
|
||||||
|
(MediaQuery.of(context).size.width * 0.8)) /
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Detail Laporan',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
_detailLaporan(_result),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _detailLaporan(Map<String, dynamic> _result) {
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
final Map<String, dynamic> _ket = jsonDecode(_result['ket']);
|
||||||
|
// ignore: prefer_typing_uninitialized_variables
|
||||||
|
var _detail;
|
||||||
|
|
||||||
|
if (_result['status'] == 'Edit Detail Produk') {
|
||||||
|
// ignore: prefer_typing_uninitialized_variables
|
||||||
|
var _namanya, _harganya, _fotonya;
|
||||||
|
if (_ket['nama_lama'] != _ket['nama_baru']) {
|
||||||
|
_namanya = Column(
|
||||||
|
children: [
|
||||||
|
Text('Nama : ${_ket['nama_lama']} => ${_ket['nama_baru']}'),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_namanya = const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_ket['harga_lama'] != _ket['harga_baru']) {
|
||||||
|
_harganya = Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Harga : Rp. ${_ket['harga_lama']} => Rp. ${_ket['harga_baru']}'),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_harganya = const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_ket['foto_lama'] != _ket['foto_baru']) {
|
||||||
|
_fotonya = Text('Foto : ${_ket['foto_lama']} => ${_ket['foto_baru']}');
|
||||||
|
} else {
|
||||||
|
_fotonya = const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
_namanya,
|
||||||
|
_harganya,
|
||||||
|
_fotonya,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Penambahan Stok') {
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Penambahan Stok : ${_ket['penambahan_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Pembelian : Rp. ${_ket['harga_pembelian_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Sebelumnya : ${_ket['jumlah_stok_sebelumnya']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Baru : ${_ket['total_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Penambahan Produk Baru') {
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Kode Barang : ${_ket['kode_barang']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Nama Barang : ${_ket['nama']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Jual : Rp. ${_ket['harga_jual']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Pembelian Stok : Rp. ${_ket['pembelian_stok']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Jumlah : ${_ket['jumlah']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else if (_result['status'] == 'Penjualan Barang Spesifik') {
|
||||||
|
_detail = Column(
|
||||||
|
children: [
|
||||||
|
Text("Jumlah Pembelian : ${_ket['jumlah_pembelian']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Harga Jual : Rp. ${_ket['harga_jual']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Sebelumnya : ${_ket['stok_sebelumnya']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text("Stok Terbaru : ${_ket['stok_sekarang']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_detail = Container();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.85,
|
||||||
|
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey,
|
||||||
|
blurRadius: 10,
|
||||||
|
spreadRadius: 1,
|
||||||
|
offset: Offset(
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text("Waktu : ${_result['waktu']}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"Status : ${(_result['status'] == 'Penjualan Barang Spesifik') ? 'Penjualan' : _result['status'].toString()}"),
|
||||||
|
const Divider(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
_detail,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleChildScrollView _pageButton() {
|
||||||
|
final List<Widget> _pageButton = <Widget>[];
|
||||||
|
|
||||||
|
if (_loadingLaporan == 1) {
|
||||||
|
if (_pageNumberLaporan >= 1 && _pageNumberLaporan <= 3) {
|
||||||
|
for (int i = 1; i <= _pageNumberLaporan; i++) {
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: (_pageNumberLaporanIndex == 1 && i == 1)
|
||||||
|
? Colors.grey
|
||||||
|
: (_pageNumberLaporanIndex == 2 && i == 2)
|
||||||
|
? Colors.grey
|
||||||
|
: (_pageNumberLaporanIndex == 3 && i == 3)
|
||||||
|
? Colors.grey
|
||||||
|
: Colors.blue,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_pageNumberLaporanIndex == 1 && i == 1) {
|
||||||
|
} else if (_pageNumberLaporanIndex == 2 && i == 2) {
|
||||||
|
} else if (_pageNumberLaporanIndex == 3 && i == 3) {
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_pageNumberLaporanIndex = i;
|
||||||
|
// _pageNumberLaporan = i;
|
||||||
|
});
|
||||||
|
_ambilLogLaporan(
|
||||||
|
context, widget.no_log, i, _filterLaporan, _cekFilter);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text(i.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (_pageNumberLaporan > 3) {
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary:
|
||||||
|
(_pageNumberLaporanIndex != 1) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilLogLaporan(context, widget.no_log,
|
||||||
|
_pageNumberLaporanIndex - 1, _filterLaporan, _cekFilter);
|
||||||
|
},
|
||||||
|
child: const Text('<'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary:
|
||||||
|
(_pageNumberLaporanIndex != 1) ? Colors.blue : Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilLogLaporan(
|
||||||
|
context, widget.no_log, 1, _filterLaporan, _cekFilter);
|
||||||
|
},
|
||||||
|
child: const Text('1'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
const Text('...'),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (_pageNumberLaporanIndex != 1 &&
|
||||||
|
_pageNumberLaporanIndex != _pageNumberLaporan) {
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
null;
|
||||||
|
},
|
||||||
|
child: Text(_pageNumberLaporanIndex.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
const Text('...'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: (_pageNumberLaporanIndex != _pageNumberLaporan)
|
||||||
|
? Colors.blue
|
||||||
|
: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilLogLaporan(context, widget.no_log, _pageNumberLaporan,
|
||||||
|
_filterLaporan, _cekFilter);
|
||||||
|
},
|
||||||
|
child: Text(_pageNumberLaporan.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_pageButton.add(
|
||||||
|
ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
primary: (_pageNumberLaporanIndex != _pageNumberLaporan)
|
||||||
|
? Colors.blue
|
||||||
|
: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_ambilLogLaporan(context, widget.no_log,
|
||||||
|
_pageNumberLaporanIndex + 1, _filterLaporan, _cekFilter);
|
||||||
|
},
|
||||||
|
child: const Text('>'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_pageButton.add(const SizedBox());
|
||||||
|
}
|
||||||
|
|
||||||
|
return SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: _pageButton,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
343
boss_app2/lib/page/login.dart
Normal file
@ -0,0 +1,343 @@
|
|||||||
|
// ignore_for_file: sized_box_for_whitespace, prefer_const_constructors
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:boss_app2/controller/login_controller.dart';
|
||||||
|
import 'package:boss_app2/controller/notification_api.dart';
|
||||||
|
import 'package:boss_app2/page/before_login.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class Login extends StatefulWidget {
|
||||||
|
// ignore: avoid_unused_constructor_parameters, prefer_const_constructors_in_immutables
|
||||||
|
Login({Key? key, String? payload}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_LoginState createState() => _LoginState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LoginState extends State<Login> {
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
//create shared prefs
|
||||||
|
late SharedPreferences sharedPreferences;
|
||||||
|
//create 2 final variables , one for the username and one for the password = TextEditingController
|
||||||
|
final TextEditingController _usernameController = TextEditingController();
|
||||||
|
final TextEditingController _passwordController = TextEditingController();
|
||||||
|
|
||||||
|
bool _isLoading = false;
|
||||||
|
late FocusNode myFocusNode;
|
||||||
|
|
||||||
|
//create void _login with 3 parameters, username, password and context
|
||||||
|
// ignore: avoid_void_async
|
||||||
|
void _login(String username, String password, BuildContext context) async {
|
||||||
|
// create final LoginController loginController = provider.of<LoginController>(context, listen: false);
|
||||||
|
final LoginController _login =
|
||||||
|
Provider.of<LoginController>(context, listen: false);
|
||||||
|
|
||||||
|
//create try catch
|
||||||
|
try {
|
||||||
|
// final Map _returnString = await _login.login(username, password);
|
||||||
|
final String _returnString = await _login.login(username, password);
|
||||||
|
|
||||||
|
//create switch case
|
||||||
|
switch (_returnString) {
|
||||||
|
case "1":
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
Future.delayed(const Duration(milliseconds: 2500), () {
|
||||||
|
// Navigator.of(context).pop(true);
|
||||||
|
// Navigator.pushAndRemoveUntil(
|
||||||
|
// context,
|
||||||
|
// MaterialPageRoute(
|
||||||
|
// builder: (context) => ScanQRCode(),
|
||||||
|
// ),
|
||||||
|
// (route) => false);
|
||||||
|
});
|
||||||
|
return const AlertDialog(
|
||||||
|
title: Text(
|
||||||
|
"Sukses",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
content: Text(
|
||||||
|
"Selamat Login Kembali",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Future.delayed(const Duration(seconds: 3), () {
|
||||||
|
// Navigator.of(context).pop(true);
|
||||||
|
Navigator.pushAndRemoveUntil(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => BeforeLogin(),
|
||||||
|
),
|
||||||
|
(route) => false);
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "2":
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
|
content: const Text("Username Dan Password Salah"),
|
||||||
|
));
|
||||||
|
//focus node
|
||||||
|
myFocusNode.requestFocus();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "3":
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
|
content: const Text(
|
||||||
|
"Error Koneksi Ke Server, Sila Periksa Jaringan Anda"),
|
||||||
|
));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
|
content:
|
||||||
|
const Text("Error Koneksi Ke Server, Sila Periksa Jaringan Anda"),
|
||||||
|
));
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore: avoid_void_async, unused_element
|
||||||
|
// void _notification() async {
|
||||||
|
// final LoginController _login =
|
||||||
|
// Provider.of<LoginController>(context, listen: false);
|
||||||
|
|
||||||
|
// //create try catch
|
||||||
|
// try {
|
||||||
|
// // final Map _returnString = await _login.login(username, password);
|
||||||
|
// final List _returnString = await _login.getNotif();
|
||||||
|
// List ini = [1, 2, 3, 4, 5];
|
||||||
|
// bool cek = false;
|
||||||
|
// int jumlah = _returnString.length;
|
||||||
|
// List notif = [];
|
||||||
|
// for (var i = 0; i < _returnString.length; i++) {
|
||||||
|
// cek = false;
|
||||||
|
// for (var j = 0; j < ini.length; j++) {
|
||||||
|
// if (ini[j].toString() == _returnString[i]['no_log'].toString()) {
|
||||||
|
// cek = true;
|
||||||
|
// jumlah = jumlah - 1;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (cek == false) {
|
||||||
|
// notif.add(int.parse(_returnString[i]['no_log']));
|
||||||
|
// }
|
||||||
|
// // cek = false;
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// }
|
||||||
|
// // NotificationApi.showNotification(
|
||||||
|
// // title: 'Notification Title',
|
||||||
|
// // body: 'Notification Body',
|
||||||
|
// // payload: 'Notification Payload',
|
||||||
|
// // );
|
||||||
|
// }
|
||||||
|
|
||||||
|
Stream<int> _getnotif(BuildContext context) async* {
|
||||||
|
// List<int> _list = [];
|
||||||
|
final LoginController _login =
|
||||||
|
Provider.of<LoginController>(context, listen: false);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
final int _data = await _login.getNotif();
|
||||||
|
await Future.delayed(Duration(seconds: 60));
|
||||||
|
yield _data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// late Timer timer;
|
||||||
|
|
||||||
|
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
|
||||||
|
FlutterLocalNotificationsPlugin();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
myFocusNode = FocusNode();
|
||||||
|
|
||||||
|
// var initializationSettingsAndroid =
|
||||||
|
// AndroidInitializationSettings('flutter_devs');
|
||||||
|
// var initializationSettingsIOs = IOSInitializationSettings();
|
||||||
|
// var initSetttings = InitializationSettings(
|
||||||
|
// android: initializationSettingsAndroid, iOS: initializationSettingsIOs);
|
||||||
|
// flutterLocalNotificationsPlugin.initialize(initSetttings,
|
||||||
|
// onSelectNotification: onSelectNotification);
|
||||||
|
NotificationApi.init(initScheduled: true, context: context);
|
||||||
|
|
||||||
|
// listenNotifications();
|
||||||
|
NotificationApi.showScheduleNotification();
|
||||||
|
// _notification();
|
||||||
|
// timer = Timer.periodic(Duration(seconds: 10), (Timer t) => _notification());
|
||||||
|
_getnotif(context).listen((data) async {
|
||||||
|
if (data > 0) {
|
||||||
|
NotificationApi.showNotification(
|
||||||
|
title: 'Laporan Baru',
|
||||||
|
body: 'Ada $data laporan baru',
|
||||||
|
payload: 'Laporan Baru',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
// timer.cancel();
|
||||||
|
super.dispose();
|
||||||
|
myFocusNode.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// // ignore: avoid_void_async
|
||||||
|
// void didChangeDependencies() async {
|
||||||
|
// super.didChangeDependencies();
|
||||||
|
// sharedPreferences = await SharedPreferences.getInstance();
|
||||||
|
// sharedPreferences.remove('notif');
|
||||||
|
// }
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
//create appbar
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Halaman Login'),
|
||||||
|
),
|
||||||
|
//create body
|
||||||
|
body: Center(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
reverse: true,
|
||||||
|
child: _isLoading
|
||||||
|
? const Center(child: CircularProgressIndicator())
|
||||||
|
: Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
// ignore: avoid_redundant_argument_values
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
// StreamBuilder(),
|
||||||
|
Container(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.8,
|
||||||
|
child: TextFormField(
|
||||||
|
focusNode: myFocusNode,
|
||||||
|
controller: _usernameController,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
hintText: "Masukkan Username",
|
||||||
|
labelText: 'Username',
|
||||||
|
),
|
||||||
|
validator: (value) {
|
||||||
|
if (value!.isEmpty) {
|
||||||
|
return 'Masukkan Username';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.8,
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _passwordController,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
obscureText: true,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
hintText: "Masukkan Password",
|
||||||
|
labelText: 'Password',
|
||||||
|
),
|
||||||
|
validator: (value) {
|
||||||
|
if (value!.isEmpty) {
|
||||||
|
return 'Masukkan Pasword';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.8,
|
||||||
|
height: 50,
|
||||||
|
child: ElevatedButton(
|
||||||
|
child: const Text('Login'),
|
||||||
|
onPressed: () {
|
||||||
|
if (_formKey.currentState!.validate()) {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
_login(_usernameController.text,
|
||||||
|
_passwordController.text, context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
// ElevatedButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// NotificationApi.showNotification(
|
||||||
|
// title: 'Notification Title',
|
||||||
|
// body: 'Notification Body',
|
||||||
|
// payload: 'Notification Payload',
|
||||||
|
// );
|
||||||
|
// // _notification();
|
||||||
|
// // sharedPreferences.re
|
||||||
|
// },
|
||||||
|
// child: Text('sini'),
|
||||||
|
// ),
|
||||||
|
// ElevatedButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// // _notification();
|
||||||
|
// NotificationApi.showScheduleNotification();
|
||||||
|
// },
|
||||||
|
// child: Text('sini 2'),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void listenNotifications() =>
|
||||||
|
// NotificationApi.onNotifications.stream.listen(onClickedNotification);
|
||||||
|
|
||||||
|
// void onClickedNotification(String? payload) {
|
||||||
|
// Navigator.of(context).push(
|
||||||
|
// MaterialPageRoute(
|
||||||
|
// builder: (context) => Login(payload: payload),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// Future onSelectNotification(String payload) {
|
||||||
|
// Navigator.of(context).push(MaterialPageRoute(builder: (_) {
|
||||||
|
// return NewScreen(Login);
|
||||||
|
// }));
|
||||||
|
|
||||||
|
// throw
|
||||||
|
// }
|
||||||
|
}
|
||||||
23
boss_app2/lib/page/superadmin/index.dart
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SuperadminIndex extends StatefulWidget {
|
||||||
|
const SuperadminIndex({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_SuperadminIndexState createState() => _SuperadminIndexState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SuperadminIndexState extends State<SuperadminIndex> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// return Scaffold
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Superadmin'),
|
||||||
|
),
|
||||||
|
body: const Center(
|
||||||
|
child: Text('Superadmin'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
boss_app2/lib/widgets/ourContainer.dart
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class OurContainer extends StatelessWidget {
|
||||||
|
final Widget? child;
|
||||||
|
|
||||||
|
const OurContainer({Key? key, this.child}) : super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final double left = (MediaQuery.of(context).size.width -
|
||||||
|
(MediaQuery.of(context).size.width * 0.9)) /
|
||||||
|
2;
|
||||||
|
return Container(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.9,
|
||||||
|
margin: EdgeInsets.only(left: left),
|
||||||
|
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey,
|
||||||
|
blurRadius: 10,
|
||||||
|
spreadRadius: 1,
|
||||||
|
offset: Offset(
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
1
boss_app2/linux/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
flutter/ephemeral
|
||||||
116
boss_app2/linux/CMakeLists.txt
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
project(runner LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(BINARY_NAME "boss_app2")
|
||||||
|
set(APPLICATION_ID "com.example.boss_app2")
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
|
||||||
|
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
|
||||||
|
|
||||||
|
# Root filesystem for cross-building.
|
||||||
|
if(FLUTTER_TARGET_PLATFORM_SYSROOT)
|
||||||
|
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
|
||||||
|
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Configure build options.
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
set(CMAKE_BUILD_TYPE "Debug" CACHE
|
||||||
|
STRING "Flutter build mode" FORCE)
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||||
|
"Debug" "Profile" "Release")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Compilation settings that should be applied to most targets.
|
||||||
|
function(APPLY_STANDARD_SETTINGS TARGET)
|
||||||
|
target_compile_features(${TARGET} PUBLIC cxx_std_14)
|
||||||
|
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
|
||||||
|
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
|
||||||
|
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
|
||||||
|
|
||||||
|
# Flutter library and tool build rules.
|
||||||
|
add_subdirectory(${FLUTTER_MANAGED_DIR})
|
||||||
|
|
||||||
|
# System-level dependencies.
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
|
||||||
|
|
||||||
|
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
|
||||||
|
|
||||||
|
# Application build
|
||||||
|
add_executable(${BINARY_NAME}
|
||||||
|
"main.cc"
|
||||||
|
"my_application.cc"
|
||||||
|
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
|
||||||
|
)
|
||||||
|
apply_standard_settings(${BINARY_NAME})
|
||||||
|
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
|
||||||
|
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
|
||||||
|
add_dependencies(${BINARY_NAME} flutter_assemble)
|
||||||
|
# Only the install-generated bundle's copy of the executable will launch
|
||||||
|
# correctly, since the resources must in the right relative locations. To avoid
|
||||||
|
# people trying to run the unbundled copy, put it in a subdirectory instead of
|
||||||
|
# the default top-level location.
|
||||||
|
set_target_properties(${BINARY_NAME}
|
||||||
|
PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Generated plugin build rules, which manage building the plugins and adding
|
||||||
|
# them to the application.
|
||||||
|
include(flutter/generated_plugins.cmake)
|
||||||
|
|
||||||
|
|
||||||
|
# === Installation ===
|
||||||
|
# By default, "installing" just makes a relocatable bundle in the build
|
||||||
|
# directory.
|
||||||
|
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
|
||||||
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Start with a clean build bundle directory every time.
|
||||||
|
install(CODE "
|
||||||
|
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
|
||||||
|
" COMPONENT Runtime)
|
||||||
|
|
||||||
|
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
|
||||||
|
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||||
|
|
||||||
|
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
|
||||||
|
COMPONENT Runtime)
|
||||||
|
|
||||||
|
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
|
||||||
|
COMPONENT Runtime)
|
||||||
|
|
||||||
|
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||||
|
COMPONENT Runtime)
|
||||||
|
|
||||||
|
if(PLUGIN_BUNDLED_LIBRARIES)
|
||||||
|
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
|
||||||
|
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||||
|
COMPONENT Runtime)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Fully re-copy the assets directory on each build to avoid having stale files
|
||||||
|
# from a previous install.
|
||||||
|
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
|
||||||
|
install(CODE "
|
||||||
|
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
|
||||||
|
" COMPONENT Runtime)
|
||||||
|
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
|
||||||
|
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
|
||||||
|
|
||||||
|
# Install the AOT library on non-Debug builds only.
|
||||||
|
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||||
|
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||||
|
COMPONENT Runtime)
|
||||||
|
endif()
|
||||||
87
boss_app2/linux/flutter/CMakeLists.txt
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
|
||||||
|
|
||||||
|
# Configuration provided via flutter tool.
|
||||||
|
include(${EPHEMERAL_DIR}/generated_config.cmake)
|
||||||
|
|
||||||
|
# TODO: Move the rest of this into files in ephemeral. See
|
||||||
|
# https://github.com/flutter/flutter/issues/57146.
|
||||||
|
|
||||||
|
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
|
||||||
|
# which isn't available in 3.10.
|
||||||
|
function(list_prepend LIST_NAME PREFIX)
|
||||||
|
set(NEW_LIST "")
|
||||||
|
foreach(element ${${LIST_NAME}})
|
||||||
|
list(APPEND NEW_LIST "${PREFIX}${element}")
|
||||||
|
endforeach(element)
|
||||||
|
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# === Flutter Library ===
|
||||||
|
# System-level dependencies.
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
|
||||||
|
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
|
||||||
|
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
|
||||||
|
|
||||||
|
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
|
||||||
|
|
||||||
|
# Published to parent scope for install step.
|
||||||
|
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
|
||||||
|
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
|
||||||
|
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
|
||||||
|
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
|
||||||
|
|
||||||
|
list(APPEND FLUTTER_LIBRARY_HEADERS
|
||||||
|
"fl_basic_message_channel.h"
|
||||||
|
"fl_binary_codec.h"
|
||||||
|
"fl_binary_messenger.h"
|
||||||
|
"fl_dart_project.h"
|
||||||
|
"fl_engine.h"
|
||||||
|
"fl_json_message_codec.h"
|
||||||
|
"fl_json_method_codec.h"
|
||||||
|
"fl_message_codec.h"
|
||||||
|
"fl_method_call.h"
|
||||||
|
"fl_method_channel.h"
|
||||||
|
"fl_method_codec.h"
|
||||||
|
"fl_method_response.h"
|
||||||
|
"fl_plugin_registrar.h"
|
||||||
|
"fl_plugin_registry.h"
|
||||||
|
"fl_standard_message_codec.h"
|
||||||
|
"fl_standard_method_codec.h"
|
||||||
|
"fl_string_codec.h"
|
||||||
|
"fl_value.h"
|
||||||
|
"fl_view.h"
|
||||||
|
"flutter_linux.h"
|
||||||
|
)
|
||||||
|
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
|
||||||
|
add_library(flutter INTERFACE)
|
||||||
|
target_include_directories(flutter INTERFACE
|
||||||
|
"${EPHEMERAL_DIR}"
|
||||||
|
)
|
||||||
|
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
|
||||||
|
target_link_libraries(flutter INTERFACE
|
||||||
|
PkgConfig::GTK
|
||||||
|
PkgConfig::GLIB
|
||||||
|
PkgConfig::GIO
|
||||||
|
)
|
||||||
|
add_dependencies(flutter flutter_assemble)
|
||||||
|
|
||||||
|
# === Flutter tool backend ===
|
||||||
|
# _phony_ is a non-existent file to force this command to run every time,
|
||||||
|
# since currently there's no way to get a full input/output list from the
|
||||||
|
# flutter tool.
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/_phony_
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E env
|
||||||
|
${FLUTTER_TOOL_ENVIRONMENT}
|
||||||
|
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
|
||||||
|
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
add_custom_target(flutter_assemble DEPENDS
|
||||||
|
"${FLUTTER_LIBRARY}"
|
||||||
|
${FLUTTER_LIBRARY_HEADERS}
|
||||||
|
)
|
||||||
11
boss_app2/linux/flutter/generated_plugin_registrant.cc
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
|
||||||
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
}
|
||||||
15
boss_app2/linux/flutter/generated_plugin_registrant.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
||||||
|
#define GENERATED_PLUGIN_REGISTRANT_
|
||||||
|
|
||||||
|
#include <flutter_linux/flutter_linux.h>
|
||||||
|
|
||||||
|
// Registers Flutter plugins.
|
||||||
|
void fl_register_plugins(FlPluginRegistry* registry);
|
||||||
|
|
||||||
|
#endif // GENERATED_PLUGIN_REGISTRANT_
|
||||||
15
boss_app2/linux/flutter/generated_plugins.cmake
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||||
|
|
||||||
|
foreach(plugin ${FLUTTER_PLUGIN_LIST})
|
||||||
|
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
|
||||||
|
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
|
||||||
|
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
|
||||||
|
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
|
||||||
|
endforeach(plugin)
|
||||||
6
boss_app2/linux/main.cc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "my_application.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
g_autoptr(MyApplication) app = my_application_new();
|
||||||
|
return g_application_run(G_APPLICATION(app), argc, argv);
|
||||||
|
}
|
||||||
104
boss_app2/linux/my_application.cc
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include "my_application.h"
|
||||||
|
|
||||||
|
#include <flutter_linux/flutter_linux.h>
|
||||||
|
#ifdef GDK_WINDOWING_X11
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "flutter/generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
struct _MyApplication {
|
||||||
|
GtkApplication parent_instance;
|
||||||
|
char** dart_entrypoint_arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
|
||||||
|
|
||||||
|
// Implements GApplication::activate.
|
||||||
|
static void my_application_activate(GApplication* application) {
|
||||||
|
MyApplication* self = MY_APPLICATION(application);
|
||||||
|
GtkWindow* window =
|
||||||
|
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
|
||||||
|
|
||||||
|
// Use a header bar when running in GNOME as this is the common style used
|
||||||
|
// by applications and is the setup most users will be using (e.g. Ubuntu
|
||||||
|
// desktop).
|
||||||
|
// If running on X and not using GNOME then just use a traditional title bar
|
||||||
|
// in case the window manager does more exotic layout, e.g. tiling.
|
||||||
|
// If running on Wayland assume the header bar will work (may need changing
|
||||||
|
// if future cases occur).
|
||||||
|
gboolean use_header_bar = TRUE;
|
||||||
|
#ifdef GDK_WINDOWING_X11
|
||||||
|
GdkScreen* screen = gtk_window_get_screen(window);
|
||||||
|
if (GDK_IS_X11_SCREEN(screen)) {
|
||||||
|
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
|
||||||
|
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
|
||||||
|
use_header_bar = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (use_header_bar) {
|
||||||
|
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
|
||||||
|
gtk_widget_show(GTK_WIDGET(header_bar));
|
||||||
|
gtk_header_bar_set_title(header_bar, "boss_app2");
|
||||||
|
gtk_header_bar_set_show_close_button(header_bar, TRUE);
|
||||||
|
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
|
||||||
|
} else {
|
||||||
|
gtk_window_set_title(window, "boss_app2");
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_window_set_default_size(window, 1280, 720);
|
||||||
|
gtk_widget_show(GTK_WIDGET(window));
|
||||||
|
|
||||||
|
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||||
|
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
|
||||||
|
|
||||||
|
FlView* view = fl_view_new(project);
|
||||||
|
gtk_widget_show(GTK_WIDGET(view));
|
||||||
|
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
|
||||||
|
|
||||||
|
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
|
||||||
|
|
||||||
|
gtk_widget_grab_focus(GTK_WIDGET(view));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements GApplication::local_command_line.
|
||||||
|
static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
|
||||||
|
MyApplication* self = MY_APPLICATION(application);
|
||||||
|
// Strip out the first argument as it is the binary name.
|
||||||
|
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
|
||||||
|
|
||||||
|
g_autoptr(GError) error = nullptr;
|
||||||
|
if (!g_application_register(application, nullptr, &error)) {
|
||||||
|
g_warning("Failed to register: %s", error->message);
|
||||||
|
*exit_status = 1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_application_activate(application);
|
||||||
|
*exit_status = 0;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements GObject::dispose.
|
||||||
|
static void my_application_dispose(GObject* object) {
|
||||||
|
MyApplication* self = MY_APPLICATION(object);
|
||||||
|
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
|
||||||
|
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void my_application_class_init(MyApplicationClass* klass) {
|
||||||
|
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
|
||||||
|
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
|
||||||
|
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void my_application_init(MyApplication* self) {}
|
||||||
|
|
||||||
|
MyApplication* my_application_new() {
|
||||||
|
return MY_APPLICATION(g_object_new(my_application_get_type(),
|
||||||
|
"application-id", APPLICATION_ID,
|
||||||
|
"flags", G_APPLICATION_NON_UNIQUE,
|
||||||
|
nullptr));
|
||||||
|
}
|
||||||
18
boss_app2/linux/my_application.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef FLUTTER_MY_APPLICATION_H_
|
||||||
|
#define FLUTTER_MY_APPLICATION_H_
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
|
||||||
|
GtkApplication)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* my_application_new:
|
||||||
|
*
|
||||||
|
* Creates a new Flutter-based application.
|
||||||
|
*
|
||||||
|
* Returns: a new #MyApplication.
|
||||||
|
*/
|
||||||
|
MyApplication* my_application_new();
|
||||||
|
|
||||||
|
#endif // FLUTTER_MY_APPLICATION_H_
|
||||||
7
boss_app2/macos/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Flutter-related
|
||||||
|
**/Flutter/ephemeral/
|
||||||
|
**/Pods/
|
||||||
|
|
||||||
|
# Xcode-related
|
||||||
|
**/dgph
|
||||||
|
**/xcuserdata/
|
||||||
1
boss_app2/macos/Flutter/Flutter-Debug.xcconfig
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||||