summaryrefslogtreecommitdiff
path: root/lib/console.dart
blob: e5bbc8b04d45c3edfee0eed73722231d41273b65 (plain)
import 'package:flutter/material.dart';

class ConsoleEntry {
  final String text;
  final bool generatedByRuntime;
  final DateTime timeGenerated;

  ConsoleEntry({
    required this.text,
    required this.generatedByRuntime,
    required this.timeGenerated,
  });
}

class _ConsoleFilter extends StatelessWidget {
  const _ConsoleFilter(this.filter, {required this.onChanged});

  final String filter;
  final Function(String filter) onChanged;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: Padding(
            padding: const EdgeInsets.only(bottom: 3),
            child: TextFormField(
              autocorrect: false,
              enableSuggestions: false,
              onChanged: onChanged,
              style: const TextStyle(fontSize: 12),
              decoration: const InputDecoration(
                contentPadding: EdgeInsets.all(6),
                labelText: "Filter: ",
              ),
            ),
          ),
        ),
        const SizedBox(width: 16),
        const Text("Console entries are only kept for several seconds"),
      ],
    );
  }
}

class _ConsoleLine extends StatelessWidget {
  const _ConsoleLine(
    this.text, {
    required this.runtime,
    required this.time,
  });

  final String text;
  final bool runtime;
  final DateTime time;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 3),
      child: DecoratedBox(
        decoration: BoxDecoration(
            color: this.runtime
                ? Colors.blue.shade900.withAlpha(128)
                : Colors.purple.shade900.withAlpha(128),
            borderRadius: const BorderRadius.all(Radius.circular(4)),
            border: Border.all(
              color: this.runtime ? Colors.blue.shade700 : Colors.purple.shade700,
              width: 3,
            )),
        child: Padding(
          padding: const EdgeInsets.all(6),
          child: Row(
            children: [
              Text(this.runtime ? "Runtime" : "Editor"),
              Expanded(
                child: Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 16),
                  child: Text(
                    this.text,
                    style: const TextStyle(fontFamily: 'Consolas'),
                  ),
                ),
              ),
              Text(
                  "${this.time.hour.toString().padLeft(2, '0')}:${this.time.minute.toString().padLeft(2, '0')}")
            ],
          ),
        ),
      ),
    );
  }
}

class ConsolePage extends StatefulWidget {
  final List<ConsoleEntry> entries;
  final void Function(String) messageFn;

  const ConsolePage(this.entries, this.messageFn, {super.key});

  @override
  State<ConsolePage> createState() => _ConsolePageState();
}

class _ConsolePageState extends State<ConsolePage> {
  String filter = "";

  @override
  Widget build(BuildContext context) {
    final controller = TextEditingController();
    final filteredMessages =
        this.widget.entries.where((e) => e.text.contains(this.filter)).toList();

    return Center(
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(children: [
          _ConsoleFilter(
            filter,
            onChanged: (newFilter) => this.setState(() => this.filter = newFilter),
          ),
          Expanded(
            child: ListView.builder(
              reverse: true,
              itemCount: filteredMessages.length,
              prototypeItem: _ConsoleLine(
                "Loading...",
                runtime: false,
                time: DateTime(1970),
              ),
              itemBuilder: (context, index) {
                final entry = filteredMessages[filteredMessages.length - index - 1];
                return _ConsoleLine(
                  entry.text,
                  runtime: entry.generatedByRuntime,
                  time: entry.timeGenerated,
                );
              },
            ),
          ),
          TextField(
            autocorrect: false,
            enableSuggestions: false,
            style: const TextStyle(fontFamily: 'Consolas'),
            controller: controller,
            decoration: const InputDecoration(hintText: "Send a console message to the runtime"),
            onSubmitted: (message) {
              this.widget.messageFn(message);
              controller.clear();
            },
          ),
        ]),
      ),
    );
  }
}