mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:27:09 -05:00 
			
		
		
		
	* feat: show stacks in asset viewer * fix: global key issue and flash on stack asset change * feat(mobile): stack and unstack action (#19941) * feat(mobile): stack and unstack action * add custom model * use stackId from ActionSource * Update mobile/lib/providers/infrastructure/action.provider.dart Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> --------- Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> * fix: lint * fix: bad merge * fix: test --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex <alex.tran1502@gmail.com> Co-authored-by: Daimolean <92239625+wuzihao051119@users.noreply.github.com> Co-authored-by: wuzihao051119 <wuzihao051119@outlook.com>
		
			
				
	
	
		
			90 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'package:analyzer/error/error.dart' show ErrorSeverity;
 | 
						|
import 'package:analyzer/error/listener.dart';
 | 
						|
import 'package:custom_lint_builder/custom_lint_builder.dart';
 | 
						|
// ignore: depend_on_referenced_packages
 | 
						|
import 'package:glob/glob.dart';
 | 
						|
 | 
						|
PluginBase createPlugin() => ImmichLinter();
 | 
						|
 | 
						|
class ImmichLinter extends PluginBase {
 | 
						|
  @override
 | 
						|
  List<LintRule> getLintRules(CustomLintConfigs configs) {
 | 
						|
    final List<LintRule> rules = [];
 | 
						|
    for (final entry in configs.rules.entries) {
 | 
						|
      if (entry.value.enabled && entry.key.startsWith("import_rule_")) {
 | 
						|
        final code = makeCode(entry.key, entry.value);
 | 
						|
        final allowedPaths = getStrings(entry.value, "allowed");
 | 
						|
        final forbiddenPaths = getStrings(entry.value, "forbidden");
 | 
						|
        final restrict = getStrings(entry.value, "restrict");
 | 
						|
        rules.add(ImportRule(code, buildGlob(allowedPaths),
 | 
						|
            buildGlob(forbiddenPaths), restrict));
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return rules;
 | 
						|
  }
 | 
						|
 | 
						|
  static LintCode makeCode(String name, LintOptions options) => LintCode(
 | 
						|
        name: name,
 | 
						|
        problemMessage: options.json["message"] as String,
 | 
						|
        errorSeverity: ErrorSeverity.WARNING,
 | 
						|
      );
 | 
						|
 | 
						|
  static List<String> getStrings(LintOptions options, String field) {
 | 
						|
    final List<String> result = [];
 | 
						|
    final excludeOption = options.json[field];
 | 
						|
    if (excludeOption is String) {
 | 
						|
      result.add(excludeOption);
 | 
						|
    } else if (excludeOption is List) {
 | 
						|
      result.addAll(excludeOption.map((option) => option));
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
 | 
						|
  Glob? buildGlob(List<String> globs) {
 | 
						|
    if (globs.isEmpty) return null;
 | 
						|
    if (globs.length == 1) return Glob(globs[0], caseSensitive: true);
 | 
						|
    return Glob("{${globs.join(",")}}", caseSensitive: true);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// ignore: must_be_immutable
 | 
						|
class ImportRule extends DartLintRule {
 | 
						|
  ImportRule(LintCode code, this._allowed, this._forbidden, this._restrict)
 | 
						|
      : super(code: code);
 | 
						|
 | 
						|
  final Glob? _allowed;
 | 
						|
  final Glob? _forbidden;
 | 
						|
  final List<String> _restrict;
 | 
						|
  int _rootOffset = -1;
 | 
						|
 | 
						|
  @override
 | 
						|
  void run(
 | 
						|
    CustomLintResolver resolver,
 | 
						|
    ErrorReporter reporter,
 | 
						|
    CustomLintContext context,
 | 
						|
  ) {
 | 
						|
    if (_rootOffset == -1) {
 | 
						|
      const project = "/immich/mobile/";
 | 
						|
      _rootOffset =
 | 
						|
          resolver.path.toLowerCase().indexOf(project) + project.length;
 | 
						|
    }
 | 
						|
    final path = resolver.path.substring(_rootOffset);
 | 
						|
 | 
						|
    if ((_allowed != null && _allowed!.matches(path)) &&
 | 
						|
        (_forbidden == null || !_forbidden!.matches(path))) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    context.registry.addImportDirective((node) {
 | 
						|
      final uri = node.uri.stringValue;
 | 
						|
      if (uri == null) return;
 | 
						|
      for (final restricted in _restrict) {
 | 
						|
        if (uri.startsWith(restricted) == true) {
 | 
						|
          reporter.atNode(node, code);
 | 
						|
          return;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
}
 |