Nanc é um novo tipo de CMS para aplicativos Flutter e não apenas para eles. É um CMS independente de back-end que não puxa seu próprio back-end. E permite que você atualize os aplicativos do Flutter sem republicá-los nas lojas. E aqui você pode jogar com aplicativos de demonstração!
Oi! Hoje quero apresentar a vocês o fruto dos meus meses de trabalho noturno e aos finais de semana, pensado para melhorar a experiência de gerenciamento de conteúdo e trazer funcionalidades adicionais ao mundo do desenvolvimento de aplicativos Flutter - um novo tipo de CMS.
Estamos falando de Nanc - N ot AN ormal C MS. Por que "não é normal" e o que você pode fazer com isso, você descobrirá depois de ler este artigo.
O artigo conterá não apenas teoria, mas também "prática" - você poderá jogar na caixa de areia Nanc. Para mostrar ao público as capacidades do Nanc, foram feitos dois aplicativos de demonstração: um aplicativo cliente que imita qualquer aplicativo Flutter e outro que dá uma ideia do que um aplicativo Nanc baseado em Flutter pode fazer - Nanc CMS pré-construído. E o aplicativo Nanc CMS, que é um CMS pré-configurado com uma camada adicional de lógica implementada para sincronizar o aplicativo cliente com o CMS.
Ao final da maioria dos blocos lógicos do texto, você encontrará um vídeo do youtube com um exemplo de como usar/demonstrar algum aspecto do Nanc.
Índice
Introdução
Sobre CMS
tipos de modelos
Coleção
Só
editor
Descrição geral
Primeiro código
Interface em primeiro lugar
modo híbrido
Campos
Bool
Cor
Data
Dinâmico
Enum
Cabeçalho
Ícone
Eu ia
MultiSeletor
Número
Seletor
Corda
Estrutura
Tela
Aplicativos dinâmicos do Flutter
Documentação interativa
Extensibilidade
Simplicidade
O poder
Conveniência
Desempenho
Aplicativos de demonstração Nanc
Em geral
Cliente
Administrador
Gerenciador de conexões
O que vem a seguir / Posfácios
Sobre o Nanc CMS
Então. O Nanc é um CMS independente de back-end que não puxa seu próprio back-end. Como funciona? A Nanc se oferece para implementar interfaces de serviço de rede, que agora têm 6 métodos, mas terão cerca de 10 no momento do lançamento. Isso é muito ou pouco? Por exemplo, foram necessárias 170 linhas de código para implementar a API do aplicativo de demonstração. Esses métodos são responsáveis por todo o trabalho do Nanc com seu back-end existente. A implementação deve ser escrita em Dart (a linguagem de desenvolvimento do Flutter também). No futuro, o Nanc virá com implementações prontas dessas interfaces para determinadas opções de back-end - Firebase, Supabase, local/rede SQLite e implementações genéricas de REST e GraphQL (talvez outra coisa?) tudo ou terá que, mas só um pouco.
tipos de modelos
Um modelo no Nanc é uma descrição estrutural de uma entidade que você deseja controlar com o Nanc. Um modelo contém um nome de entidade, vários parâmetros visuais e uma descrição dos campos.
Coleção
Uma coleção é uma entidade que pode ter muitas instâncias. Uma lista de usuários, livros e resenhas são bons exemplos de modelos do tipo Coleção em Nanc.
Se você estiver familiarizado com bancos de dados relacionais, um exemplo de Coleção em Nanc seria quase qualquer tabela em seu banco de dados.
Só
Um solo (modelo) é uma entidade que existe em uma única instância. Por exemplo - Alternância de recursos ou uma configuração de algo, ou... "A tela principal de um aplicativo móvel". De um modo geral, os Solo-models são projetados para aumentar a usabilidade, sendo apenas uma projeção do seu banco de dados. E um modelo Solo pode facilmente ser qualquer tabela em seu banco de dados com apenas um registro. Mas, no momento, a implementação dessa classe de modelos exige que o registro desse modelo (linha no banco de dados) tenha um id igual ao id do próprio modelo.
final Model landingPage = Model( name: 'Landing page', /// ? id in format [toSnakeCase(name)] will be set automatically, if omitted // id: 'landing_page', isCollection: false, icon: IconPackNames.flu_document_page_break_regular, fields: [ ...
editor
Descrição geral
O Nanc pode ser configurado de várias formas: por código, pela própria interface do Nanc e uma combinação dessas opções.
Configuração de código primeiro
Quando digo "configuração", quero dizer, antes de tudo, descrever a estrutura de seus modelos. Vamos dar um exemplo simples, o modelo Feature, que é uma entidade que descreve as funcionalidades de um produto. Esta entidade contém os seguintes campos:
eu ia
título
imagem
descrição
E a implementação como uma configuração code-first será a seguinte:
Ao descrever esse modelo e usá-lo no Nanc CMS, todas as operações CRUD desse modelo ficam disponíveis para você.
Configuração de primeira interface
Poderíamos criar exatamente o mesmo modelo de recurso (vamos chamá-lo de variante de recurso) por meio da interface Nanc. E (considerando que todo o trabalho preparatório para o uso do Nanc está feito) - ao criar um modelo no Nanc, você criará imediatamente uma tabela no banco de dados, e todo o CRUD também estará disponível para você imediatamente.
Além disso, você pode seguir o caminho mais seguro de não criar nada no banco de dados ao criar um modelo por meio da interface Nanc. E crie uma tabela de forma independente em seu banco de dados e, abaixo dela, crie um modelo no Nanc. A propósito, isso é o que você deve fazer se descrever a configuração em código - novas tabelas não aparecerão em seu banco de dados a partir dele.
Configuração híbrida
Esta opção fica disponível para você quando você tem uma configuração Code-first e decide alterá-la através da interface Nanc. Nesse caso, todas as alterações posteriores nesse modelo só serão possíveis por meio da interface, e as alterações feitas no modelo de código original serão ignoradas. A única maneira de retornar ao Code-first é "redefinir" o modelo, caso em que todas as alterações na estrutura do modelo feitas por meio da interface serão apagadas e a configuração do Code-first será usada novamente. Nenhum dado é afetado por esta redefinição. Afeta apenas a estrutura do modelo.
Campos
Agora vamos ver quais tipos de campos o Nanc suporta atualmente.
boleano
BoolField permite controlar o tipo de dados bool e personalizar o valor padrão.
Cor
O ColorField fornece um seletor de cores útil que permite escolher uma cor imediatamente no Nanc. Ele também oferece a capacidade de fazer alterações manualmente, editando o código AHEX. AHEX é uma cor HEX clássica (por exemplo, #10A0CF ), mas com um valor de transparência adicional especificado primeiro. Neste caso, esta cor seria semelhante à cor #FF10A0CF ( FF é 100% opacidade - a cor é completamente opaca). E é assim que a mesma cor ficaria com 50% de opacidade: #7F10A0CF .
Data
DateField é responsável por controlar data e hora (os dois valores ao mesmo tempo, valores separados para data e hora serão implementados posteriormente). DateField contém dois parâmetros booleanos que permitem modificar o comportamento desse campo, tornando-o um carimbo de hora de criação de entidade e um carimbo de hora de mudança.
Dinâmico
DynamicField, por um lado, é um campo muito simples, mas, por outro lado, inclui toda a complexidade dos outros campos. Inicialmente, você pode configurar apenas a aparência deste campo (como ficará na interface do Nanc - a cor e o ícone que o acompanha). Depois disso, este campo pode conter quaisquer valores disponíveis no Nanc, inclusive ele próprio. O que isto significa? Essencialmente, DynamicField é um JSON digitado com a capacidade de posicionar os campos em ordem dentro de si.
Enum
EnumField é um campo para selecionar um valor de vários valores. A regra a seguir ao selecionar um EnumField é que, se você tiver uma lista final de valores para selecionar que não esteja armazenada em uma tabela de banco de dados separada, escolha Enum. Caso contrário, escolha SelectorField, que é discutido com mais detalhes abaixo. TODO: No momento este campo só pode ser configurado via CodeConfig, configuração via interface não está funcionando.
Cabeçalho
HeaderField não é realmente um campo, mas um aprimorador visual para seu modelo no Nanc. Você pode usar este campo não para definir um cabeçalho comum para um grupo de campos relacionados ou para distinguir campos de modelo uns dos outros usando HeaderField como um delimitador.
Ícone
IconField permite selecionar um ícone (classe IconData ) de um conjunto predefinido de ícones. Existem atualmente cerca de 25.000 deles, e este conjunto inclui os seguintes ícones:
Se necessário, outros ícones podem ser adicionados ao conjunto básico de entrega e, em um futuro não muito distante, haverá a opção de usar seus próprios ícones também.
Alguém pode se perguntar: "Os ícones estão lá, as cores estão lá, mas as fontes?" Se sim, você pode encontrar a resposta na documentação do widget Texto . A resposta curta é que todas as fontes do estão disponíveis para você.
Eu ia
IdField é um campo tão simples, mas tão importante. Todo modelo gerenciado pelo Nanc deve possuir pelo menos um campo do tipo Id. Atualmente, apenas o tipo de ID de string é suportado (pode ser qualquer string exclusiva dentro de uma entidade). Existem planos para adicionar suporte para tipo numérico também, que, no entanto, pode ser implementado mesmo agora simplesmente convertendo os dados do campo para o tipo numérico na implementação da API.
Multisseletor
MultiSelectorField é um campo bastante complexo que é responsável por implementar um relacionamento relacional muitos-para-muitos ou muitos-para-um. Existem três modos de usar este campo. Vamos percorrer cada um deles com mais detalhes. TODO: No momento este campo só pode ser configurado através do CodeConfig, a configuração através da interface não está funcionando.
Matriz de IDs
Este modo oferece a capacidade de armazenar o id de entidades relacionadas diretamente na entidade pai. Por exemplo - temos dois modelos - Leitor e Livro. Neste modo, os livros levados pelo leitor serão contabilizados como ids armazenados no campo Modelo do leitor. Por exemplo assim:
Acima está um exemplo de estrutura de tabela expressa usando a sintaxe JSON5.
A desvantagem desse modo é a integridade limitada dos dados. Se você não implementar a remoção automática de IDs de livros obsoletos (excluídos) do campo Leitor de books , você receberá erros.
terceira mesa
O modo clássico de fornecer relacionamentos do mundo SQL. Ao usar este modo, você armazena os relacionamentos entre entidades em uma tabela separada e garante 100% de integridade dos dados. A estrutura a seguir é um exemplo desse modo:
No 7º segundo você pode ver uma leve contração e se você olhar de perto você pode notar que o url da página mudou - foi assim que tentei esconder o bug: no terceiro modo de tabela os dados são salvos na página pai somente se já foi salvo 🤷🏼
Matriz de objetos
Geralmente semelhante ao Array de ids, exceto que o registro pai não armazena identificadores, mas o objeto inteiro (como uma estrutura plana, sem possíveis entidades associadas ao registro aninhado). Tem a mesma desvantagem do Array of ids, mas tem uma desvantagem adicional - maior uso de armazenamento. No entanto existe (pelo menos por enquanto) uma área de aplicação deste modo, e é muito importante. Mas vamos falar sobre isso um pouco mais tarde.
Estou me adiantando no vídeo, mostrando o ScreenField, já voltaremos a isso
Em geral, existe a ideia de tornar os modos "não canônicos" virtuais - para que funcionem de alguma forma na Terceira tabela e os dados necessários sejam carregados ao editar a página (se necessário).
Número
NumberField armazena números - simples assim.
Seletor
SelectorField é semelhante a MultiSelectorField (como você pode imaginar pelos nomes), mas um pouco mais simples - a relação aqui é um-para-um ou um-para-muitos, e há dois modos. TODO: No momento este campo só pode ser configurado via CodeConfig, configuração via interface não está funcionando.
Eu ia
Uma forma comum de fornecimento de link SQL, em que o campo de registro pai armazena a ID do registro vinculado. Tomemos o Reader como exemplo. Quem é esse? Em primeiro lugar, é uma pessoa, e o que uma pessoa tem? Isso mesmo! A cidade de nascimento (que nossa Biblioteca, por algum motivo, também queria saber).
Muito semelhante ao Array de objetos do MultiSelectorField, mas armazenaremos um único valor associado no campo do registro pai. As desvantagens são as mesmas, as vantagens também serão descritas um pouco abaixo.
Corda
StringField armazena strings. Este campo possui uma configuração pessoal responsável pela comodidade de edição no Nanc - o parâmetro que limita a altura máxima do campo editável. Se o seu texto for grande - faz sentido não especificá-lo, o campo se ajustará à altura do texto. Se limitado a grande - você pode especificar a altura do campo explícito (em linhas) e sempre será assim. E, finalmente, para strings curtas, você pode configurá-lo para uma linha e, em seguida, o campo não se expandirá, não importa o quanto você escreva nele depois.
Estrutura
StructureField permite que você armazene uma matriz de estruturas digitadas em registros de modelo. Você especifica o tipo de dados a serem armazenados e pode gerenciá-los de maneira fácil e simples. Os tipos disponíveis para campos de estrutura são absolutamente tudo. Assim, você pode criar facilmente uma "Repetição de campo de estrutura dinâmica". TODO: Somente campos "planos" podem ser adicionados ao StructureField dentro da demonstração.
Tela
ScreenField é um campo que permite escrever uma aplicação inteira no Flutter, direto no Nanc! Com o ScreenField, você pode descrever a interface de uma única tela, atualizá-la como quiser e fazê-lo a qualquer momento em minutos - sem a espera tediosa e angustiante por análises da Apple e do Google.
Vamos detalhar um pouco mais esse tipo de campo (e, na verdade, todo um desdobramento funcional separado do Nanc).
Aplicativos dinâmicos do Flutter
Com ScreenField, você pode realmente criar uma interface de quase qualquer complexidade diretamente em seu navegador (e seu IDE) e, em seguida, sem fazer uma publicação de estoque, atualizar a tela correspondente em seu aplicativo. Se você precisa verificar hipóteses rapidamente, esse é um ótimo recurso. Essa funcionalidade é ótima para páginas relativamente simples (em termos de lógica) em seu aplicativo, que, no entanto, precisam ser alteradas com bastante frequência. No futuro, essa funcionalidade será expandida para um estado em que você pode realmente criar o que quiser, sem nenhuma restrição. Agora vamos percorrer todos os aspectos da criação de telas dinâmicas com o Nanc.
Documentação interativa
Existem muitos widgets no Flutter. Muitos deles. O que é um widget? É um tijolo de funcionalidade a partir do qual você monta seu aplicativo. Pode ser apenas visual ou pode ser lógico - com algum comportamento interno. O Nanc fornece uma extensa lista de widgets implementados que você pode usar para construir sua IU. Mas quanto mais possibilidades - mais difícil é aprender sobre eles... Portanto, o editor de tela do Nanc oferece acesso a uma documentação interativa onde você pode descobrir quais widgets estão implementados atualmente, quais parâmetros e propriedades configuráveis eles possuem e, diretamente na documentação, veja como eles afetam a aparência da interface que você cria.
Simplicidade
O Nanc permite que você crie uma interface em tempo real, mas o mais importante - permite que você faça isso com muita facilidade e rapidez (levou um pouco mais de 2 horas para fazer a interface de um aplicativo de demonstração). Mas surge a pergunta - como criar a própria interface do usuário? Não existe uma sintaxe exótica para descrever a interface do usuário no Nanc, nem soluções "muito" simples, como JSON longo, que farão você odiar a criação de interfaces no Nanc.
O resultado de encontrar a melhor solução é uma sintaxe XML simples e direta. Todos os widgets Flutter padrão têm exatamente os mesmos nomes, mas em formato XML. Por exemplo, o widget SizedBox no Nanc seria <sizedBox>...</sizedBox> , e esta regra se aplica a todos os widgets sem exceção. Se o widget tiver alguma propriedade complexa, ele terá o mesmo nome (ou mais simples) do XML, com o prefixo prop . Por exemplo - o widget Container possui uma propriedade complexa boxDecoration , que possui suas próprias propriedades internas. Assim, esta propriedade no Nanc terá o seguinte aspecto: <prop:decoration>...</prop:decoration> . Esta regra se aplica a todas as propriedades complexas. E o último aspecto é que argumentos relativamente simples são parâmetros de tags XML. Vamos pegar o mesmo SizedBox como exemplo:
<sizedBox width="50" height="50"> ... </sizedBox>
Para alguns widgets, argumentos adicionais são implementados para simplificar a escrita do código e, para SizedBox , é o argumento ize que define width e height .
Tudo o que está escrito aqui está na documentação online, então se você esquecer alguma coisa ou quiser saber alguma coisa, consulte-a e encontre lá as respostas para todas as suas dúvidas.
Extensibilidade
Implemente o suporte para o novo widget - uma questão de 10 minutos a algumas horas. Neste ponto, quase todos os widgets básicos são implementados, dos quais você pode criar uma interface complexa com lógica. Com o tempo, todos os widgets disponíveis no Flutter serão implementados no Nanc, e você pode realmente fazer tudo. Mas isso não é tudo. Você pode facilmente e simplesmente implementar seus próprios widgets e usá-los no Nanc com uma ou duas linhas de código XML. Por exemplo - não há widget na biblioteca padrão do Flutter que permita exibir facilmente o controle deslizante de carrossel com imagens. Você mesmo terá que escrever uma implementação ou usar alguma solução de código aberto como . E, tendo implementado o que você precisa - você pode facilmente integrar seu widget ao Nanc e usá-lo.
O poder
O Nanc fornece mais do que apenas a capacidade de converter código XML em uma interface no Flutter. O Nanc fornece recursos de criação de modelos e lógica. Renderização de elemento condicional, desenho de loop, manipulação de toque - isso já está na versão 0.0.1 atual do Nanc.
Até agora, a parte lógica é bastante direta - ela oferece suporte à interação por meio de toques e manipulação de eventos em seu código `.dart' escrito com antecedência - mas, eventualmente, essa parte do Nanc se expandirá consideravelmente, permitindo que você escreva lógica em Dart diretamente no navegador e fazê-lo funcionar em seu aplicativo também.
A abordagem para lidar com os cliques do usuário é a seguinte - você pode definir uma lista de "ações" que o usuário pode realizar em seu aplicativo. Por exemplo - abra a tela interna do aplicativo, clique no link externo, exiba o SnackBar, abra a janela modal e muitas outras coisas e crie um manipulador para tais ações com antecedência. E então use essa ação da maneira que quiser no Nanc. Para obter mais informações sobre manipulação de eventos, consulte a documentação do widget InkWell no Nanc.
Conveniência
O Nanc possui um editor de XML embutido, mas não é muito prático. Não é pesquisável (ainda), não é muito rápido com muito código e não possui preenchimento automático. Como viver com isso? Por exemplo - deixe o usuário usar seu IDE favorito e observe as alterações no Nanc em tempo real. Deixa-me mostrar-te como. E esta é a Web (que é o que você tem para brincar):
Futuramente será adicionado suporte ao autocomplete, talvez num futuro distante...Tentei me aprofundar no XML Schema, passei vários dias, mas até agora não consegui 🤷🏼♀️
Desempenho
Separadamente, gostaria de mencionar o desempenho (desenho de interface de XML em dispositivos móveis). Resumindo, é idêntico ao desempenho do próprio Flutter, sem nenhum overhead. No momento, a "tela" é uma lista de widgets renderizada lentamente (SliverList), criada de forma assíncrona. Posteriormente, essa implementação será refinada para começar a renderizar os widgets de forma assíncrona, mas por sua vez, para que o tempo necessário para exibir o conteúdo seja igual ao tempo que leva para renderizar o primeiro widget descrito no XML.
Aplicativos de demonstração Nanc
Em geral
Para demonstrar os recursos, um conjunto público de aplicativos de demonstração foi criado para mostrar o que pode ser alcançado com o Nanc no momento. Este é um aplicativo cliente no Android e na Web (este último também desempenha temporariamente o papel de um aplicativo iOS). Bem como o aplicativo Nanc CMS. Leia mais sobre eles abaixo.
links
Cliente
Client é um aplicativo de demonstração do cliente que usa uma única biblioteca do ecossistema nanc. Esta biblioteca permite converter XML em uma interface de aplicativo no Flutter. Esta aplicação possui apenas uma tela, criada inteiramente em Nanc, podendo ser atualizada conforme desejado e a qualquer momento sem necessidade de almoxarifados. No canto inferior direito existe um botão com um ícone de conexão - é responsável por conectar-se ao . Mais sobre o que será essa "conexão" abaixo.
Administrador
Admin é um aplicativo de demonstração Nanc-CMS, com uma camada de lógica implementada adicionalmente, que fornece a capacidade de sincronizar com clientes (mais sobre a conexão abaixo). No aplicativo de demonstração Nanc-CMS, o próprio navegador do usuário e seu localStorage atuam como o "back-end". Tudo o que você adiciona ou altera é armazenado apenas no seu navegador. No Nanc-CMS você pode modificar/criar/excluir dados relacionados aos modelos existentes (você os verá), e - você pode criar seus próprios modelos através da interface e fazer o mesmo com eles.
Como uma representação SQL dos modelos de dados usados na criação desta demonstração, você pode ser guiado pela seguinte captura de tela:
Gerenciador de conexão / "Conexão"
Esta seção refere-se exclusivamente à lógica da "demonstração" nos aplicativos cliente e CMS. E foi implementado para simular a experiência de interação com o Nanc e o processo de atualização do cliente. Mas as primeiras coisas primeiro.
Em um projeto de produção real, você poderia usar o Nanc da seguinte maneira: implantar um aplicativo Nanc CMS estático em algum lugar, com serviços de API implementados. Ele se comunicaria com seu back-end e você usaria o Nanc ao seu gosto. Seu aplicativo contém uma biblioteca do ecossistema nanc que permite renderizar a interface. Você fez uma atualização - o aplicativo carregou um novo código do seu back-end, atualizado - todos estão felizes e satisfeitos.
Para mostrar esse modelo em ação, implementamos o mesmo, mas de forma simplificada: O Nanc CMS existe como estático, nas páginas do github e você pode usá-lo como "na vida real", mas seu navegador atua como back-end. Ou seja, as APIs foram implementadas de forma que "vão para a rede" - no navegador localStorage. Com esta parte terminamos, mas ainda existe um aplicativo móvel, que deve de alguma forma mostrar o processo de "atualização".
Bem, é aí que entra a "conexão". Resumindo - você pode estabelecer uma conexão direta entre qualquer aplicativo de demonstração do cliente Nanc e qualquer aplicativo de demonstração do Nanc CMS. Para fazer isso, você precisa clicar no botão inferior direito com o ícone do código QR no CMS. Na janela modal que aparece, você verá o código QR. Em seguida, você tem duas cadeiras - você pode escanear este código com o aplicativo cliente móvel (ou navegador) pressionando o botão semelhante no canto inferior direito, então a conexão será estabelecida automaticamente. Ou você pode clicar no código QR e os dados necessários para a conexão serão copiados para a área de transferência. Então você terá que colar esses dados no campo de entrada do aplicativo móvel e conectar pressionando o botão. Quando a conexão for estabelecida - você se entenderá. Depois disso, você pode fazer o que quiser com a Landing Page existente e ver as alterações em tempo real (após salvar) - no aplicativo móvel.
Mas você não está limitado à Landing Page . Você pode criar novos modelos diretamente no navegador, preenchê-los com conteúdo e, se seus modelos tiverem um campo para descrição da interface (tipo Tela) - então, ao salvar essas entidades, você também verá o resultado no aplicativo - o tela do novo modelo substituirá a tela do aplicativo existente. O único ponto é que, como a aplicação cliente não sabe que tipo de campo é o seu registro recém-criado, ela possui possíveis identificadores prescritos, que se espera que sejam ScreenFields.
Portanto, se você deseja criar uma tela inteiramente do zero e exibi-la no aplicativo, use algo da lista a seguir como o valor de IdField:
tela
interface do usuário
página
interface
marcação
visualizar
Se você quebrar alguma coisa - basta redefinir os dados (Chrome: F12 -> Aplicativo -> Aplicativo -> Armazenamento -> Limpar dados do site), bem, quando você reabrir o aplicativo cliente, ele sempre carregará o código de tela real criado para esta demonstração. (O código do seu navegador será carregado apenas se você se conectar)
E por fim, um pequeno exemplo de criação de uma nova página de um novo modelo contendo um ScreenField e renderizando-o na aplicação:
Qual é o próximo?
A demonstração pública está pronta. O artigo introdutório está escrito. Planos futuros para Nanc - para completar a integridade funcional da abordagem de interface para criação de modelo, tornando possível configurar todos os campos - Enum, Selector e MultiSelector. Corrija bugs conhecidos, como alterar a posição dos elementos no StructureField. Depois "blah blah blah" e depois "fulano de tal". A lista de pendências será suficiente para o próximo semestre, pelo menos, mas o modelo adicional de expansão da funcionalidade será baseado nas necessidades do cliente, portanto, se você tiver ideias/críticas/bugs encontrados (e há muitos deles) /qualquer outra coisa - preencha o formulário, cujo link está disponível no aplicativo de demonstração do cliente.
Se você está interessado nos recursos do Nanc e está interessado em cooperação - preencha o formulário também e com certeza conversaremos.