<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Edeilton Oliveira</title>
    <description>The latest articles on Forem by Edeilton Oliveira (@edeilton).</description>
    <link>https://forem.com/edeilton</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1151008%2F359258f7-db2f-4649-8065-501da76d264d.jpg</url>
      <title>Forem: Edeilton Oliveira</title>
      <link>https://forem.com/edeilton</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/edeilton"/>
    <language>en</language>
    <item>
      <title>Utilizando pseudo-elementos do CSS e interfaces no TypeScript</title>
      <dc:creator>Edeilton Oliveira</dc:creator>
      <pubDate>Sun, 11 Feb 2024 06:25:58 +0000</pubDate>
      <link>https://forem.com/edeilton/utilizando-pseudo-elementos-do-css-e-interfaces-no-typescript-4c66</link>
      <guid>https://forem.com/edeilton/utilizando-pseudo-elementos-do-css-e-interfaces-no-typescript-4c66</guid>
      <description>&lt;p&gt;&lt;em&gt;Hoje vamos misturar CSS com TypeScript no mesmo post para entender como construir interfaces usando pseudo-elementos e interfaces! (what?)&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Revisei pseudo-elementos no CSS durante o desenvolvimento do temporizador disponível &lt;a href="https://github.com/EdeiltonSO/IgniteTimer" rel="noopener noreferrer"&gt;aqui nesse link&lt;/a&gt;, mas não é de hoje que esses seletores me chamam a atenção. Acho interessantíssima a ideia de poder criar e estilizar um elemento que é renderizado em tela, sem a necessidade de adicionar elementos extras ao HTML ou ter que usar JavaScript.&lt;/p&gt;

&lt;p&gt;Na especificação desse projeto, há uma tabela com uma coluna de status que tem uma bolinha (que pode assumir três cores diferentes) e o título do status, conforme mostrado abaixo, na coluna mais à direita:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnehvccyxu39yz1a7xxwa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnehvccyxu39yz1a7xxwa.jpg" alt="Image description" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para criar essa bolinha, talvez o seu primeiro pensamento seja usar um componente estilizado dentro do &lt;code&gt;td&lt;/code&gt; de status da tabela (mesmo que não seja um componente em outro arquivo, já que é algo simples). Daí teríamos dois elementos: a bolinha e o texto, com um gap entre eles. &lt;/p&gt;

&lt;p&gt;Mas dá pra fazer melhor: pode ser só o texto com um &lt;code&gt;::before&lt;/code&gt;. E se você ainda não sabe o que é isso, vem comigo que eu te explico — e se já sabe, vem relembrar!&lt;/p&gt;

&lt;h2&gt;
  
  
  Utilizando pseudo-elementos
&lt;/h2&gt;

&lt;p&gt;Resumidamente, &lt;code&gt;::before&lt;/code&gt; e &lt;code&gt;::after&lt;/code&gt; são pseudo-elementos do CSS criados, respectivamente, &lt;strong&gt;antes&lt;/strong&gt; e &lt;strong&gt;depois&lt;/strong&gt; da coisa que você tá estilizando. No exemplo abaixo (que utiliza Styled Components), estou criando a bolinha &lt;strong&gt;antes&lt;/strong&gt; dessa div estilizada, já que ela fica à esquerda do texto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  display: flex;
  align-items: center;
  gap: 0.5rem;

  ::before {
    content: '';
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yellow-500&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;;
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O background desse pseudo-elemento utiliza uma arrow function com &lt;code&gt;props.theme&lt;/code&gt; somente por conta do Theme Provider da aplicação, mas você não precisa se preocupar com isso agora. Se preferir, por enquanto, imagine apenas uma cor fixa em hexadecimal e teremos o mesmo resultado.&lt;/p&gt;

&lt;p&gt;Lembre-se que mesmo que você não queira exibir conteúdo algum dentro do pseudo-elemento, é sempre necessário usar o &lt;code&gt;content: '';&lt;/code&gt;, caso contrário, ele não aparece na tela. Já na estrutura da página, cada linha da tabela será assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tarefa X&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;30 minutos&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Há 3 meses&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Concluído&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;td&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora que o texto e a bolinha já aparecem na página, vamos pro próximo passo: mudar a cor de acordo com o status do componente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adicionando uma interface em TypeScript
&lt;/h2&gt;

&lt;p&gt;Como alterar a cor no arquivo de estilos de acordo com o status da tarefa? Fácil: passando propriedades, mais ou menos como fazemos em componentes JSX.&lt;/p&gt;

&lt;p&gt;Para isso, você pode criar uma interface no arquivo de estilos e passar pro componente usando os &lt;em&gt;generics&lt;/em&gt; do TypeScript. Confira abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;StatusProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;statusColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StatusProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;``&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E não podemos esquecer de passar a propriedade ao usar o componente lá na estrutura da página:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt; &lt;span class="na"&gt;statusColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"green"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Concluído&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“E aí, tá pronto?” &lt;/p&gt;

&lt;p&gt;Não.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definindo a constante de cores
&lt;/h2&gt;

&lt;p&gt;A cor ainda não muda pois tá fixa dentro do estilo do Status (no primeiro snippet de código desse post) e as cores que estamos utilizando ficam em um objeto que tá em outro arquivo, pois a aplicação utiliza o ThemeProvider do Styled Components. Você pode conferir conferir as constantes de cor no arquivo &lt;a href="https://github.com/EdeiltonSO/IgniteTimer/blob/main/src/styles/themes/main.ts" rel="noopener noreferrer"&gt;src/styles/themes/main.ts&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Para ter acesso a esses valores, uma solução é criar uma constante STATUS_COLORS, como é mostrado a seguir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;STATUS_COLORS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green-500&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yellow-500&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red-500&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por fim, lembra do background com o &lt;code&gt;props.theme&lt;/code&gt; que poderia ser uma cor fixa? Agora precisamos tornar ela dinâmica, de acordo com o Theme Provider e a constante de cores que acabamos de definir. Veja no exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;STATUS_COLORS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusColor&lt;/span&gt;&lt;span class="p"&gt;]]};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou seja: pegue a propriedade &lt;code&gt;statusColor&lt;/code&gt; (disponível nas &lt;code&gt;props&lt;/code&gt; do componente), utilize como índice no objeto &lt;code&gt;STATUS_COLORS&lt;/code&gt; e, com o valor retornado, acesse a cor desejada no &lt;code&gt;theme&lt;/code&gt; do provider (também disponível via &lt;code&gt;props&lt;/code&gt;, no arquivo &lt;a href="https://github.com/EdeiltonSO/IgniteTimer/blob/main/src/App.tsx" rel="noopener noreferrer"&gt;App.tsx&lt;/a&gt; da aplicação).&lt;/p&gt;

&lt;p&gt;Com isso — e contando que seu Theme Provider esteja configurado — o componente já deve alterar a cor da bolinha conforme o status passado por meios das propriedades. Lindo, né?&lt;/p&gt;

&lt;p&gt;Vamos revisar o funcionamento:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O componente Status recebe a cor pela propriedade &lt;code&gt;statusColor&lt;/code&gt; lá no JSX;&lt;/li&gt;
&lt;li&gt;O estilo dele pega esse valor via &lt;em&gt;generic&lt;/em&gt; do TypeScript — que está recebendo a interface &lt;code&gt;StatusProps&lt;/code&gt;, definida nos estilos;&lt;/li&gt;
&lt;li&gt;Essa interface fixa que os valores aceitos são os mesmos da constante &lt;code&gt;STATUS_COLORS&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Os valores das chaves na constante &lt;code&gt;STATUS_COLORS&lt;/code&gt; coincidem com os nomes das cores fornecidas pelo Theme Provider no arquivo App.tsx;&lt;/li&gt;
&lt;li&gt;O Theme Provider recebe o objeto &lt;code&gt;mainTheme&lt;/code&gt;, contendo os hexadecimais das cores.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Facilitando a manutenção
&lt;/h2&gt;

&lt;p&gt;Perceba que, na etapa 3 da revisão acima, os valores possíveis para a interface devem coincidir com a constante. Mas e se uma nova cor de status for adicionada ao componente? Precisamos editar a constante e a interface? &lt;/p&gt;

&lt;p&gt;Até aí sim, mas podemos evitar isso adaptando a interface &lt;code&gt;StatusProps&lt;/code&gt; para que &lt;code&gt;statusColor&lt;/code&gt; sempre se ajuste aos valores das chaves da constante &lt;code&gt;STATUS_COLORS&lt;/code&gt;. Confira:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;StatusProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;statusColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;STATUS_COLORS&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois de dessa alteração, sabemos que sempre vamos ter uma equivalência entre as chaves de &lt;code&gt;STATUS_COLORS&lt;/code&gt; e a lista de cores aceitas pela nossa interface. Agora não precisamos mexer em dois lugares ao modificar a lista de cores — basta alterar a constante.&lt;/p&gt;

&lt;p&gt;Pronto! Agora, com tudo configurado, basta chamar o componente Status passando a propriedade que corresponda ao status da tarefa.&lt;/p&gt;

&lt;p&gt;Concluímos que, além de uma solução bastante elegante, os pseudo-elementos no CSS são ferramentas excelentes para adicionar elementos em tela sem poluir o HTML ou recorrer ao JavaScript. &lt;/p&gt;

&lt;p&gt;Em relação ao uso de interfaces em TypeScript e uma constantes de cores, percebemos que essas soluções tornam a implementação mais flexível e fácil de se adaptar a mudanças posteriores do projeto — o que torna a manutenção do código muito mais simples.&lt;/p&gt;

&lt;p&gt;Curtiu aprender um pouco mais sobre o mundo do desenvolvimento front-end? Então me segue que em breve tem mais!&lt;/p&gt;

</description>
      <category>css</category>
      <category>typescript</category>
      <category>frontend</category>
      <category>react</category>
    </item>
    <item>
      <title>Personalizando o modelo de usuário do Django</title>
      <dc:creator>Edeilton Oliveira</dc:creator>
      <pubDate>Sat, 02 Dec 2023 16:37:50 +0000</pubDate>
      <link>https://forem.com/edeilton/personalizando-o-modelo-de-usuario-do-django-3g44</link>
      <guid>https://forem.com/edeilton/personalizando-o-modelo-de-usuario-do-django-3g44</guid>
      <description>&lt;p&gt;&lt;em&gt;Quer usar o seu próprio modelo de usuário na autenticação do Django? Vem comigo que eu te ensino em 4 passos simples!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;O Django é uma ferramenta bastante útil para acelerar o processo de desenvolvimento de software pois já entrega diversas funcionalidades comuns — entre elas, um sistema de autenticação com um modelo próprio de usuário, que será o foco das próximas linhas.&lt;/p&gt;

&lt;p&gt;Se você está desenvolvendo um projeto nesse framework e seus models incluem uma classe de usuário que não é nativa dele, ela não será lida automaticamente como um modelo para autenticação de usuário.&lt;/p&gt;

&lt;p&gt;O que acontece é que, ao implementar a autenticação para usuários por meio da função helper &lt;code&gt;create_user()&lt;/code&gt;, o Django cria uma tabela própria de usuários, ignorando o modelo e as características que você definiu no arquivo &lt;code&gt;models.py&lt;/code&gt;. Isso pode ser um problema quando o modelo de usuário da sua aplicação tem atributos específicos ou, ainda, é referenciado por Foreign Keys (FK) em outros modelos.&lt;/p&gt;

&lt;h2&gt;
  
  
  AbstractUser e AbstractBaseUser
&lt;/h2&gt;

&lt;p&gt;Para resolver isso, precisamos criar um modelo personalizado baseado no modelo padrão do Django e existem duas maneiras de fazer isso: estendendo &lt;code&gt;AbstractUser&lt;/code&gt; ou &lt;code&gt;AbstractBaseUser&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Escolhendo &lt;code&gt;AbstractUser&lt;/code&gt;, você estenderá uma classe que inclui recursos normalmente utilizados em modelos de usuário. Isso inclui campos como &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;first_name&lt;/code&gt; e &lt;code&gt;last_name&lt;/code&gt;, além de &lt;a href="https://docs.djangoproject.com/en/4.2/ref/contrib/auth/#user-model" rel="noopener noreferrer"&gt;outros atributos e métodos&lt;/a&gt; para funcionalidades comuns relacionadas à manipulação de usuários.&lt;/p&gt;

&lt;p&gt;Enquanto isso, &lt;code&gt;AbstractBaseUser&lt;/code&gt; fornece apenas o mínimo necessário para um modelo de usuário. Não inclui os campos citados anteriormente e é mais adequada quando você deseja ter controle total sobre o modelo de usuário, permitindo que você defina seus próprios campos. &lt;/p&gt;

&lt;p&gt;Nesse último caso, como é especificado pela &lt;a href="https://docs.djangoproject.com/en/4.2/topics/auth/customizing/#specifying-a-custom-user-model" rel="noopener noreferrer"&gt;documentação&lt;/a&gt; do framework, você também precisa definir o campo de nome de usuário (usado como login) e os campos obrigatórios do modelo por conta própria.&lt;/p&gt;

&lt;h2&gt;
  
  
  Executando o passo a passo
&lt;/h2&gt;

&lt;p&gt;Nesse caso, vamos escolher &lt;code&gt;AbstractUser&lt;/code&gt; pois é uma classe mais completa e já fornece, entre outros, os campos de nome de usuário e senha.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passo 1: crie o novo modelo de usuário
&lt;/h3&gt;

&lt;p&gt;No arquivo &lt;code&gt;models.py&lt;/code&gt;, faça o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AbstractUser&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AbstractUser&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;bio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Adicione características personalizadas conforme necessário
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe que não é necessário incluir campos básicos de login, como nome de usuário, e-mail e senha, pois eles já estão presentes em &lt;code&gt;AbstractUser&lt;/code&gt;. Além disso, por padrão, o Django não trata o campo de e-mail como único na tabela, portanto, se desejar que isso seja feito, especifique isso na definição do &lt;code&gt;CustomUser&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;EmailField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois da definição, use &lt;code&gt;CustomUser&lt;/code&gt; como FK onde for necessário nos outros modelos. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CustomUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Passo 2: atualize as configurações do projeto
&lt;/h3&gt;

&lt;p&gt;No arquivo &lt;code&gt;settings.py&lt;/code&gt;, certifique-se de que a aplicação faça parte do projeto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;app&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Informe também que o modelo de autenticação que deve ser utilizado pelo Django agora é o seu modelo customizado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;AUTH_USER_MODEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;app.CustomUser&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nos dois casos, lembre-se de alterar &lt;code&gt;app&lt;/code&gt; pelo nome da sua aplicação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passo 3: personalize a interface administrativa
&lt;/h3&gt;

&lt;p&gt;No arquivo &lt;code&gt;admin.py&lt;/code&gt;, importe e registre os novos modelos e, se desejar, utilize &lt;code&gt;list_display&lt;/code&gt; para definir quais campos do modelo serão exibidos no painel de administração do Django:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.admin&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;UserAdmin&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CustomUser&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomUserAdmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserAdmin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;list_display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bio&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;created_at&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;is_staff&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CustomUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CustomUserAdmin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se não quiser personalizar a exibição com o &lt;code&gt;list_display&lt;/code&gt;, use a palavra reservada &lt;code&gt;pass&lt;/code&gt; no lugar. O painel administrativo exibirá a tabela de usuários com os campos padrão do &lt;code&gt;AbstractUser&lt;/code&gt;. Isso não influenciará nos atributos do model, é apenas um ajuste para a exibição dos registros.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passo 4: aplique as mudanças no banco de dados
&lt;/h3&gt;

&lt;p&gt;Finalmente, execute os comandos &lt;code&gt;makemigrations&lt;/code&gt; e &lt;code&gt;migrate&lt;/code&gt; para aplicar as modificações ao banco de dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python manage.py makemigrations app
&lt;span class="nv"&gt;$ &lt;/span&gt;python manage.py migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E claro, mais uma vez, lembre-se de alterar &lt;code&gt;app&lt;/code&gt; pelo nome da sua aplicação.&lt;/p&gt;

&lt;p&gt;Depois de seguir esse passo a passo, você poderá utilizar o sistema de autenticação do Django ao mesmo tempo em que mantém as características específicas do seu modelo de usuário.&lt;/p&gt;

&lt;p&gt;E aí, gostou? Se liga aí que em breve tem mais post ;)&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>model</category>
      <category>user</category>
    </item>
    <item>
      <title>Root, flash e custom ROM no Xperia X8 (e um pouco de história)</title>
      <dc:creator>Edeilton Oliveira</dc:creator>
      <pubDate>Wed, 13 Sep 2023 00:40:13 +0000</pubDate>
      <link>https://forem.com/edeilton/root-flash-e-custom-rom-no-xperia-x8-e-um-pouco-de-historia-27cd</link>
      <guid>https://forem.com/edeilton/root-flash-e-custom-rom-no-xperia-x8-e-um-pouco-de-historia-27cd</guid>
      <description>&lt;p&gt;&lt;em&gt;Como fazer o root, o flash de um recovery e instalar uma custom ROM no Sony Ericsson Xperia X8 de um jeito fácil (dentro do possível).&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Se você só tá precisando do tutorial (o que eu duvido muito, já que estamos em 2023) e quer ir direto pra ele, vá para o próximo subtítulo. Aqui eu vou falar brevemente sobre &lt;strong&gt;por que&lt;/strong&gt; quis inaugurar meu blog com um tutorial de custom ROM pra um smartphone idoso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Um pouco de história
&lt;/h2&gt;

&lt;p&gt;A real é que eu sempre gostei de documentar coisas, explicar, fazer tutoriais e registrar a minha história. Meus celulares fizeram parte disso e traquinar no sistema deles era meu &lt;em&gt;hobby&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Em uma dessas eu comprei um Xperia X8 que rodava Android 2.1 e uma das limitações daquela versão era que os aplicativos não podiam ser movidos para o cartão de memória — e a memória interna dele era bastante limitada.&lt;/p&gt;

&lt;p&gt;Pensei "vou comprar e atualizar pro Froyo" (aliás, quem lembra de quando a Google nomeava as versões do robozinho com nomes de doces? Bons tempos). O problema era que a Sony Ericsson já tinha encerrado o ciclo de atualizações dele — que iniciou no Android 1.6 — o que me obrigava a ir pras custom ROMs.&lt;/p&gt;

&lt;p&gt;O então projeto CyanogenMod era a melhor (senão a única) opção para isso e só dependia de uma aplicação de recovery personalizada — que, por sua vez, dependia de um sistema com root. Digo com segurança que o X8 foi o aparelho que mais me deu trabalho pra fazer tudo isso e é por isso que decidi fazer um tutorialzinho lá na época, pro caso de precisar no futuro.&lt;/p&gt;

&lt;p&gt;Juntei links, anotei passos que executei graças aos tutoriais que fui lendo e no fim tive uma documentação tão bonita que quis compartilhar com quem mais tivesse interesse e, pra isso, mandei pra um blog que acompanhava, sugerindo a publicação.&lt;/p&gt;

&lt;p&gt;O tutorial foi publicado lá em 2012 e sempre levei isso como algo especial &lt;del&gt;na minha carreira de construtor de tutoriais&lt;/del&gt;. Hoje, 11 anos depois, quero manter essa história viva, então trouxe ele pra cá.&lt;/p&gt;

&lt;p&gt;E aí, quer saber como instalar uma custom ROM no Xperia X8? Vem comigo que eu te ensino — ou melhor, o Edeilton do passado vai te ensinar!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a id="o-tutorial"&gt;&lt;/a&gt; O tutorial
&lt;/h2&gt;

&lt;p&gt;Daqui em diante siga por sua conta e risco e, caso decida continuar, não esqueça de fazer backup. Esse processo irá apagar todos os dados que estejam armazenados na memória interna.&lt;/p&gt;

&lt;p&gt;Os links pra download dos programas estão no fim do tutorial, mas depois de mais de uma década, não funcionam mais. Mantive apenas pra ter uma lista fácil do que baixar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Root do sistema
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Instale o PC Companion;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execute o SuperOneClick como administrador;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No celular, vá em &lt;code&gt;Configurações&lt;/code&gt; &amp;gt; &lt;code&gt;Aplicativos&lt;/code&gt; &amp;gt; &lt;code&gt;Desenvolvimento&lt;/code&gt; &amp;gt; &lt;code&gt;Depuração USB&lt;/code&gt; e marque essa opção;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conecte-o por USB ao PC e aguarde reconhecer;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em “Root” na barra superior do SuperOneClick e aguarde o término do processo;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em OK nas possíveis mensagens e veja na área de notificações do lado esquerdo se o processo continua. Caso não, reconecte o aparelho e tente novamente;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para saber se deu certo, veja no celular se foi instalado um aplicativo chamado “SuperUser”. Se sim, está pronto. Se não, refaça o processo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flash do xRecovery
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Baixe o xRecovery e copie os arquivos que estiverem contidos nele para o cartão de memória do celular;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Baixe no Android Market, o ES Explorador de Arquivos;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Baixe o Root Explorer, e transfira-o para o cartão de memória do X8;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Com o ES, procure o Root Explorer, instale-o e depois reinicie o aparelho;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Com o Root Explorer, procure os arquivos do xRecovery (busybox, chargemon e xrecovery.tar) e copie um por um para a pasta &lt;code&gt;/system/bin&lt;/code&gt; do celular. Antes de colá-los na pasta, procure no topo do Root Explorer, um botão chamado “Mount RW”, toque nele, depois cole os arquivos (deverá ficar como “Mount RO”).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reinicie o aparelho e ao aparecer o nome e logo da Sony Ericsson, segure no botão de voltar. Se aparecer uma tela com opções em inglês e um Android Trollface ao fundo, o xRecovery foi instalado corretamente. Se não, refaça o processo.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Flashtool
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Baixe o FlashTool e extraia numa pasta (você pode mudar o idioma do programa em Languages e mudar para Portuguese, se quiser);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Baixe o arquivo de Firmware e Baseband;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vai ter uma série de arquivos. Crie uma pasta (por exemplo, “i15a_2.1.1.A.0.6_Xperia”) na pasta &lt;code&gt;firmware&lt;/code&gt; do FlashTool, descompacte e jogue os arquivos lá. A pasta &lt;code&gt;firmware&lt;/code&gt; pode estar localizada na pasta do usuário ou no disco C.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Baixe o Loader (x8.sin), renomeie ele para loader.sin e substitua o loader.sin da pasta &lt;code&gt;i15a_2.1.1.A.0.6_Xperia&lt;/code&gt; que você acabou de criar;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execute o Flashtool como admin, vá em &lt;code&gt;Avançadas&lt;/code&gt; &amp;gt; &lt;code&gt;Criar Bundle&lt;/code&gt;. Ao selecionar a pasta, escolha o local onde você extraiu os arquivos. Há alguns campos de textos que você deve preencher e você pode colocar qualquer coisa, mas a sugestão é preencher com &lt;code&gt;i15a&lt;/code&gt;, &lt;code&gt;2.1.1.A.0.6&lt;/code&gt; e &lt;code&gt;Xperia&lt;/code&gt; nos campos &lt;code&gt;Telemóvel&lt;/code&gt;, &lt;code&gt;Versão&lt;/code&gt; e &lt;code&gt;Branding&lt;/code&gt;, respectivamente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passe todos os arquivos listados na janela da esquerda para a direita. Para isso, selecione todos, clique na seta para a direita &lt;br&gt;
e clique em OK. Ele irá criar um arquivo &lt;code&gt;.tft&lt;/code&gt; que será jogado automaticamente para a pasta &lt;code&gt;firmware&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ainda com o Flashtools aberto, clique em Flash, escolha o arquivo Firmware e de OK. Espere alguns segundos e uma janela com instruções irá aparecer.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;7.1. Desconecte o celular, desligue e aguarde 10 segundos;&lt;/p&gt;

&lt;p&gt;7.2. Conecte o cabo USB no celular enquanto segura o botão voltar;&lt;/p&gt;

&lt;p&gt;7.3. Solte o botão voltar quando um LED verde acender na parte superior do aparelho. Feito isso, aguarde o término do processo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instalando a custom ROM
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Transfira a ROM para a raiz do cartão de memória;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Renomeie para “update” (mantenha a extensão .zip);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reinicie o aparelho com o botão voltar pressionado;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ao abrir o xRecovery, acesse &lt;code&gt;Factory Reset (full wipe)&lt;/code&gt; e confirme a ação;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vá até &lt;code&gt;Wipe cache partition&lt;/code&gt; e confirme, se necessário;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finalmente, vá em &lt;code&gt;Install update.zip from SD card&lt;/code&gt; e confirme;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aguarde o término do processo e reinicie;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Caso o celular não saia da tela de boot, refaça todos os passos de instalação da custom ROM.&lt;/p&gt;

&lt;p&gt;Pronto! Agora o seu Xperia X8 está com Android 2.2 CyanogenMod estável :D&lt;/p&gt;

&lt;h3&gt;
  
  
  Links (que não funcionam mais)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.4shared.com/zip/j084AUix/SuperOneClick.html" rel="noopener noreferrer"&gt;SuperOneClick&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.4shared.com/file/Ux607J5q/Sony_PC_Companion_210053_Web.html" rel="noopener noreferrer"&gt;PC Companion&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.4shared.com/file/_WtFGiP_/xRecovery.html?cau2=403tNull" rel="noopener noreferrer"&gt;xRecovery&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.estrongs.android.pop" rel="noopener noreferrer"&gt;ES Explorador de Arquivos&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.4shared.com/android/RkVVO6Et/Root_Explorer__File_Manager__v.htm" rel="noopener noreferrer"&gt;Root Explorer&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.4shared.com/file/ZbgjMiWa/FlashTool_0291.html" rel="noopener noreferrer"&gt;FlashTool&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.4shared.com/file/R3JwSItI/Xperia_X8_E15a_1243-9502.html" rel="noopener noreferrer"&gt;Firmware e Baseband&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.4shared.com/file/v4sXmOT6/x8_online.html?cau2=403tNull" rel="noopener noreferrer"&gt;Loader (x8.sin)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://download.cyanogenmod.org/?device=shakira&amp;amp;type=stable" rel="noopener noreferrer"&gt;ROM CyanogenMod estável&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>xperia</category>
      <category>x8</category>
      <category>root</category>
      <category>customrom</category>
    </item>
  </channel>
</rss>
