Traducir subtítulos de cursos en Edx.org

A veces no tomamos algunos cursos porque no dominamos del todo el idioma en el que esta, sin poder entender del todo lo que dictan es difícil de llevar , para eso podemos usar la opción de traductor que tiene Google Chrome.

Vamos al curso de edx.org, en este caso estoy inscrito en AWS Developer: Building on AWS

Antes con solo indicar que se traduzca la página , las subtítulos del video también se traducían (esta forma aún funciona en Udemy,com )

Por ejemplo voy a la página:
https://learning.edx.org/course/course-v1:AWS+OTP-AWSD1+2T2019/block-v1:AWS+OTP-AWSD1+2T2019+type@sequential+block@9ac4fc392af34c7d9796d0fdd367550e/block-v1:AWS+OTP-AWSD1+2T2019+type@vertical+block@9415479f6cfc4db099dbb7eb1bc5fa11
e indico que lo traduzca.

Los textos de la página se han traducido

pero no los subtítulos del video

Entonces, hacemos click en “inicio de la transcripción, salta al final

Noten que la url y la página cambiaron

Nueva Url:
https://courses.edx.org/xblock/block-v1:AWS+OTP-AWSD1+2T2019+type@vertical+block@9415479f6cfc4db099dbb7eb1bc5fa11?show_title=0&show_bookmark_button=0&recheck_access=1&view=student_view#transcript-end-5f15e942439b440ebc3cd7a1b13908a5

Página

indicamos que se traduzca la pagina completa, si no aparece la opción en la url, también se pueden hacerlo con click derecho>traducir a español

Reproducen el video y notarán que ya esta traducido

Listo.

Crear librerías comunes entre aplicaciones Flutter

Desarrollando un sistema, que consta de dos apps según el rol del usuario, ( conductor y pasajero, vendedor y comprador, administrador y empleado, etc ), percate que si bien ya puedo desplegar en ambas plataformas, hay partes de la interfaz y la API que se repite, solo la lógica parece única, entonces surge la necesidad de compartir este código común.

La primera solución fue copiar el código en un paquete dentro de lib, pero como esta en desarrollo se repetirá muchas veces ese paso lo cual suena doloroso, así que probare el concepto de cómo compartirlo entre ambas apps.

bueno, al código.

Creamos 3 aplicaciones: Cliente1, Cliente2 y Librería

$ flutter create --org=com.example.cliente1 Cliente1
$ flutter create --org=com.example.cliente2 Cliente2
$ flutter create --org=com.example.libreria Libreria

Trabajaré en la aplicación Cliente1 agregando la librería y luego repetiré lo mismo en la Cliente2 para comprobarlo.

Lo que necesito probar en este caso es :
– Si se puede compartir widgets
– Si la librería tiene dependencias, estas deben cargarse en la principal o se puede obviar.
– Si se puede configurar variables en la librería desde el cliente.

Tomando el caso del sistema, una parte común entre ambas apps, es el chat.

Primero trabajaremos en la librería

Librería

Para probar cada requerimiento se hará:

– Si se puede compartir widgets.
Se implementará un widget del botón que iniciara el chat que cada cliente colocara donde lo necesite.

– Si la librería tiene dependencias, estas deben cargarse en la principal o se puede obviar.
Se usará un paquete de iconos en la librería.

– Si se puede configurar variables en la librería desde el cliente
Se seteará un parámetro que es global en la librería, para ver como se comporta en el cliente..

Primero implementé como si fuera un proyecto normal para verificar su funcionamiento, separando los componentes que serán reusables.

Repositorio:

https://github.com/JavierSolis/Flutter_DemoLibreria_Libreria

Los cambios para hacerlo librería son:

  • Crear un archivo “lib_chat.dart” donde indican que archivos serán expuestos para los clientes. ( nota: aún no tengo ni he visto un convención para los nombres, por el momento le colocare el prefijo de lib_*)
  • Al momento de usarlo en cliente, no se puede usar las dependencias que se uso en la librería, pero si se exponen, por ejemplo “flutter_icons.dart”, se pueden usar en el cliente.
  • Se creo un nuevo widget “widget_button_chat.dart”, solo para encerrar en una clase el botón del chat y usarlo en el cliente.
library lib_chat;

//expone el wiget button
export 'widget/widget_button_chat.dart';
//expone la página del chat
export 'page/chat_page.dart';
//expone la configuración que usa el chat
export 'constants.dart';

//agregado después para exponer la dependencia que se uso en la librería
export 'package:flutter_icons/flutter_icons.dart';
import 'package:Libreria_chat/page/chat_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';

class ButtonChatWidget extends StatelessWidget {
  final String urlContactPhoto;
  final String nameContact;
  const ButtonChatWidget({Key key, this.nameContact, this.urlContactPhoto})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: () {
        Navigator.pushReplacement(
            context,
            MaterialPageRoute(
                builder: (BuildContext context) => ChatPage(
                    contactName: this.nameContact,
                    urlContactPhoto: this.urlContactPhoto)));
      },
      child: Icon(AntDesign.message1),
    );
  }
}
  • En pubspec.yaml no es necesario ningún cambio, pero para poder identificarlo mejor, cambie el nombre a “libreria_chat“, eso conllevo cambiar el paquete en algunos archivos.
name: Libreria_chat
description: Libreria de chat
...
import 'package:Libreria_chat/constants.dart';
import 'package:Libreria_chat/widget/widget_chat.dart';
import 'package:flutter/material.dart';

class ChatPage extends StatelessWidget {

Repositorio:

https://github.com/JavierSolis/Flutter_DemoLibreria_Libreria_refactorizado

Cliente 1

Para usar la librería en el Cliente 1, se agrega la dependencia en pubspec.yaml. indicando el nombre “Libreria_chat” y la ruta “path:

...
dependencies:
  flutter:
    sdk: flutter
  Libreria_chat:
    path: ../LibreriaRefactorizado #ruta a la librería

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.0
...

En main.dart , agregue el botón button_chat_widget y un icono de una dependencia de la librería Icon(AntDesign.message1) ( esto se pudo después de exponerlo en la librería por defecto sus dependencias no están disponibles) y se configuro la variable constante en la librería CHAT_USER_NAME.

import 'package:Libreria_chat/constants.dart';
import 'package:Libreria_chat/widget/widget_button_chat.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Cliente 1'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    CHAT_USER_NAME = "Javier Solis";
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Icon(AntDesign.message1),
              Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
        ),
        floatingActionButton: ButtonChatWidget(
          urlContactPhoto:
              "https://crop-circle.imageonline.co/images/picture.png",
          nameContact: "Raul",
        ));
  }
}

Video:

Repositorio:

https://github.com/JavierSolis/Flutter_DemoLibreria_Cliente_1

y listo.


Tenemos una librería que podemos rehusar. Ahora podemos tener una librerías de utilitarios que podemos usar en todas nuestras app ( notificaciones, login, control de permisos , etc) que ahorrara tiempo en configurar, en grupo de apps conductor/cliente, etc.

Notas adicionales:

  • Si tengo abierto la librería y hago un cambio, luego haces hotreload en el cliente, los cambios en la librería se cargarán.
  • No implemente el cliente 2, porque los pasos son los mismos al cliente 1.
  • La librería también se puede publicar en pub.dev o referenciar desde github.

Referencias:

Iconos de ejemplo
https://pub.dev/packages/flutter_icons

Lista
https://googleflutter.com/flutter-add-item-to-listview-dynamically/

Border rounded
https://stackoverflow.com/a/57778500

Como desinstalar WOW y Battle.net

Primero ingresar a la plataforma de battle.net

Escoger el juego

Mas abajo seleccionar el juego a desinstalar

Mas arriba buscar la el menu “opciones”

Y escoger “Desinstalar”

Y en la ventana escoger “Si, desinstalar”

Y esperar que termine de desistalar.

Para desinstalar la plataforma puede seguir las instrucciones oficiales, excepto el último paso:
https://eu.battle.net/support/es/article/30304

Para Mac recomendable usar AppCleaner.app

Escoger la app y abajo click en “buscar”.

Luego click en “borrar” y listo.

Referencias:

https://eu.battle.net/support/es/article/30333
https://www.youtube.com/watch?v=taMka_wrT7k
https://eu.battle.net/support/es/article/30304