Could not reach Cloud Firestore backend. Connection failed 1 times. Most recent error: FirebaseError: [code=unknown]: Fetching auth token failed: getToken aborted

 Esto ocurre cuando se guarda el proyecto en Visual Code (lo cual vuelve a recargar todo) y despues se intenta hacer el login.

Es como si quisiera usar el token viejo para autenticarse.

La solucion, borrar los datos de navegacion (Ctrl+Shift+Supr)

Y luego darle Ctrl-P a la página.

Can't bind to 'formGroup' since it isn't a known property of 'form'

 -en declarations, agregar los componentes (ej, EdicionVehiculosComponent)

-en imports agregar:

CommonModule,
FormsModule,
ReactiveFormsModule


@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    EdicionVehiculosComponent,
    ListadoVehiculosComponent
  ],

  imports: [

    BrowserModule,
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    AppRoutingModule,
    AngularFireModule.initializeApp(firebaseConfig),
    AngularFirestoreModule,
    AngularFireStorageModule
  ],

  providers: [],
  bootstrap: [AppComponent]
})

Instalar macOS en VirtualBox + instalar IONIC con XCode

Instalar macOS

 https://techsprobe.com/6-step-install-macos-catalina-on-virtualbox-on-windows-pc/


ATENCION!!!

sudo ionic cordova build ios

si da este error:

xcode-select: error: tool 'xcodebuild' requires Xcode


Abrir XCode / Preferences / Locations

Ver la ruta que dice en Command Line Tools

sudo xcode-select --switch /Users/crusso/Downloads/XCode-beta.app

Luego, abrir con XCode el archivo nombre.xcodeproj


Deploying a IOS con XCode

https://ionicframework.com/blog/deploying-to-a-device-without-an-apple-developer-account/#:~:text=First%20off%2C%20yes%2C%20you%20do,a%20paid%20Apple%20Developer%20account.



Scroll no funciona en android con Hammer y evento (press)


<ion-content>
  <ion-list>
    <ion-item *ngFor="let reclamo of listaReclamos" (click)="historialReclamo(reclamo)" (press)="prueba(reclamo.id, reclamo.texto)">
      <ion-label text-wrap>{{reclamo.texto}}</ion-label>

      <ion-note slot="end">{{reclamo.fecha.toMillis() | date:'dd/MM/yyyy HH:mm'}} <br> 
                           {{reclamo.nickUsuario}} <br>
                           
        <ion-badge *ngIf="reclamo.estado == 'resuelto'" color="success">resuelto</ion-badge>
        <ion-badge *ngIf="reclamo.estado == 'atrasado'" color="danger">atrasado</ion-badge>
        <ion-badge *ngIf="reclamo.estado == 'pendiente'" color="warning">pendiente</ion-badge>
      </ion-note>
    </ion-item>
  </ion-list>

  <ion-fab vertical="bottom" horizontal="end" slot="fixed">
    <ion-fab-button (click)="nuevoReclamo()">
      <ion-icon name="add"></ion-icon>
    </ion-fab-button>
  </ion-fab>
</ion-content>

 al utilizar (press), deja de andar el scroll en la lista

para solucionarlo,

en app.module.ts, poner en false pinch y rotate:

export class CustomHammerConfig extends HammerGestureConfig {
  overrides = {
      'press': { time: 1000 },  //set press delay for 1 second
      'pinch': { enable: false },
      'rotate': { enable: false }
  }
}


Chroma con Adobe After Effects

Chroma en Adobe After Effects

1. Elegir herramienta pluma y marcar borde del sujeto (mover la linea de tiempo para ver si queda todo dentro)
2. Effects / Keying / Keylight
3. Click en el gotero, y luego en la parte verde
4. View / Combined matte
5. Ajustar el verde (a la izquierda del gotero) hasta que se vayan las manchas del fondo
6. Screen Matte / Clip white (bajarlo)
7.              / Clip black (subirlo)
8. View / Final Result
10. Replace method / hard color
11. Screen shrink / glow  -1
12. Screen softness / 1
13. Effect / Color Correction / Lumetri Color
14. Basic correction / White balance / Temperature (ajustar)
                     / Shadows (bajar)
       / Whites (subir)
15. Layer / New / Solid / Elegir color verde / mover layer para abajo del video

Para ver la mascara de nuevo:

GitHub - Subir proyectos

Crear el repositorio en github.com (ej, nombre: gastos)

cd <path fuente>
git init
          git add .                     //agrega todos los archivos
          gitt add -all (o -a)     //agrega los archivos nuevos solamente y los que tuvieron cambios

git commit -m "agrego archivos"

//solo la 1ra vez:
git remote add origin https://github.com/cmrusso/gastos.git
git push origin master

//todas las siguientes veces
git push


(si hay problemas, git push --force origin master)


Para actualizar cambios

git commit -m "descripcion del cambio"
git push origin master


ClickOnce - ejecutar como administrador


Si se armó un setup con ClickOnce, no es posible -por diseño- ejecutarlo como administrador.

Para solucionarlo, agregar esto en el inicio de la aplicación.
Lo que hace basicamente es arrancar un nuevo proceso como administrador, y matar al actual.


private bool IsRunAsAdministrator()
{
var wi = WindowsIdentity.GetCurrent();
var wp = new WindowsPrincipal(wi);

return wp.IsInRole(WindowsBuiltInRole.Administrator);
}

private void Application_Startup(object sender, StartupEventArgs e)
{
if (!IsRunAsAdministrator())
{
    // It is not possible to launch a ClickOnce app as administrator directly, so instead we launch the
    // app as administrator in a new process.
    var processInfo = new ProcessStartInfo(Assembly.GetExecutingAssembly().CodeBase);

    // The following properties run the new process as administrator
    processInfo.UseShellExecute = true;
    processInfo.Verb = "runas";
        
    // Start the new process
    try
    {
        Process.Start(processInfo);
    }
    catch (Exception)
    {
        // The user did not allow the application to run as administrator
        MessageBox.Show("Sorry, this application must be run as Administrator.");
    }

    // Shut down the current process
    Environment.Exit(0);
}
else
{
    // We are running as administrator
        
    // Do normal startup stuff...
}
}



Fuente:
http://antscode.blogspot.com/2011/02/running-clickonce-application-as.html


Joystick con arduino Leonardo y teclas de flecha

#include <Button.h>
#include <Keyboard.h>

const int BOTON_UP = 4;
const int BOTON_DOWN = 5;
const int BOTON_LEFT = 2;
const int BOTON_RIGHT = 3;

const int BOTON_A = 10;
const int BOTON_B = 8;
const int BOTON_X = 9;

const int BOTON_COIN = 11;

const int BOTON_1P = 7;
const int BOTON_2P = 6;

Button btnUp = Button(BOTON_UP,PULLUP);
Button btnDown = Button(BOTON_DOWN,PULLUP);
Button btnLeft = Button(BOTON_LEFT,PULLUP);
Button btnRight = Button(BOTON_RIGHT,PULLUP);

Button btnA = Button(BOTON_A, PULLUP);
Button btnB = Button(BOTON_B, PULLUP);
Button btnX = Button(BOTON_X, PULLUP);

Button btnCoin = Button(BOTON_COIN, PULLUP);

Button btn1P = Button(BOTON_1P, PULLUP);
Button btn2P = Button(BOTON_2P, PULLUP);

void setup() {
  Keyboard.begin();
}

void loop() { 
  if (btnUp.isPressed()) { 
    Keyboard.press(KEY_UP_ARROW);
  } else {
    Keyboard.release(KEY_UP_ARROW);   
  }

  if (btnDown.isPressed()) { 
    Keyboard.press(KEY_DOWN_ARROW);
  } else {
    Keyboard.release(KEY_DOWN_ARROW);   
  }

  if (btnLeft.isPressed()) { 
    Keyboard.press(KEY_LEFT_ARROW);
  } else {
    Keyboard.release(KEY_LEFT_ARROW);   
  }

  if (btnRight.isPressed()) { 
    Keyboard.press(KEY_RIGHT_ARROW);
  } else {
    Keyboard.release(KEY_RIGHT_ARROW);   
  }

  if (btnA.isPressed()) { 
    Keyboard.press(97);
  } else {
    Keyboard.release(97);
  } 

  if (btnB.isPressed()) { 
    Keyboard.press(98);
  } else {
    Keyboard.release(98);
  } 

  if (btnX.isPressed()) { 
    Keyboard.press(120);
  } else {
    Keyboard.release(120);
  } 

  if (btnCoin.isPressed()) { 
    Keyboard.press(53);
  } else {
    Keyboard.release(53);
  } 

  if (btn1P.isPressed()) { 
    Keyboard.press(49);
  } else {
    Keyboard.release(49);
  } 

  if (btn2P.isPressed()) { 
    Keyboard.press(50);
  } else {
    Keyboard.release(50);
  } 
}












---------------------------------------------------------------------------------------------------------------
VERSION ANTERIOR


#include <Button.h>
#include <Keyboard.h>

const int BOTON_UP = 4;
const int BOTON_DOWN = 5;
const int BOTON_LEFT = 2;
const int BOTON_RIGHT = 3;

const int BOTON_X = 10;
const int BOTON_Y = 8;
const int BOTON_Z = 9;

const int BOTON_A = 11;
const int BOTON_B = 12;

const int BOTON_1P = 7;
const int BOTON_2P = 6;

Button btnUp = Button(BOTON_UP,PULLUP);
Button btnDown = Button(BOTON_DOWN,PULLUP);
Button btnLeft = Button(BOTON_LEFT,PULLUP);
Button btnRight = Button(BOTON_RIGHT,PULLUP);

Button btnX = Button(BOTON_X, PULLUP);
Button btnY = Button(BOTON_Y, PULLUP);
Button btnZ = Button(BOTON_Z, PULLUP);

Button btnA = Button(BOTON_A, PULLUP);
Button btnB = Button(BOTON_B, PULLUP);

Button btn1P = Button(BOTON_1P, PULLUP);
Button btn2P = Button(BOTON_2P, PULLUP);

void setup() {
  Keyboard.begin();
}

void loop() { 
  if (btnUp.isPressed()) {   
    Keyboard.press(KEY_UP_ARROW);
  } else {
    Keyboard.release(KEY_UP_ARROW);     
  }

  if (btnDown.isPressed()) {   
    Keyboard.press(KEY_DOWN_ARROW);
  } else {
    Keyboard.release(KEY_DOWN_ARROW);     
  }

  if (btnLeft.isPressed()) {   
    Keyboard.press(KEY_LEFT_ARROW);
  } else {
    Keyboard.release(KEY_LEFT_ARROW);     
  }

  if (btnRight.isPressed()) {   
    Keyboard.press(KEY_RIGHT_ARROW);
  } else {
    Keyboard.release(KEY_RIGHT_ARROW);     
  }

/*  if (btnEnter.isPressed()) {   
    Keyboard.press(90);
  } else {
    Keyboard.release(90);
  } 
*/
  if (btnX.isPressed()) {   
    Keyboard.press(65);
  } else {
    Keyboard.release(65);
  } 

  if (btnY.isPressed()) {   
    Keyboard.press(66);
  } else {
    Keyboard.release(66);
  } 

  if (btnZ.isPressed()) {   
    Keyboard.press(88);
  } else {
    Keyboard.release(88);
  } 

  if (btnA.isPressed()) {   
    Keyboard.press(53);
  } else {
    Keyboard.release(53);
  } 

/*
  if (btnB.isPressed()) {   
    Keyboard.press(11);
  } else {
    Keyboard.release(11);
  } 
*/
  if (btn1P.isPressed()) {   
    Keyboard.press(49);
  } else {
    Keyboard.release(49);
  } 

  if (btn2P.isPressed()) {   
    Keyboard.press(50);
  } else {
    Keyboard.release(50);
  } 


}

Youtube broadcast live con OBS



1. Ir a https://studio.youtube.com/

2. Click en la camara (con el signo de mas) y Transmitir en Vivo, crear nueva transmisión

3. En Youtube Creator, copiar la clave de transmisión

4. En OBS, ir a Herramientas/Config automatica, next, next, y poner la clave de transmision

5. En OBS, click en iniciar transmision (abajo a la derecha)

6. En Youtube Creator, Iniciar transmision

7. Ir a Archivo / Configuracion / Salida

                Setear el bitrate:

                Hacer test de velocidad del adsl: https://www.speedtest.net/
                Si por ej, dice velocidad de subida 8mbps, poner en Bitrate de video 8000kbps
             
                Para ver tabla de bitrates: https://support.google.com/youtube/answer/1722171?hl=es-419

                Bajar audio bitrate (probar)

   Si se quiere grabar: setear en donde dice Recording



Angular en IE - Habilitar custom headers y cors en WebApi (SEC7123)

Proyecto de ejemplo que tiene este cambio: Creditos


A partir de Angular 8 no es necesario modificar el archivo polyfills.


1. Agregar en WebApiConfig.cs

            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors(cors);

2. Agregar en web.config (dentro de 

  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <!-- <add name="Access-Control-Allow-Origin" value="*" />  -->
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
 
  </system.webServer>