Showing posts with label How Tos. Show all posts
Showing posts with label How Tos. Show all posts

Android java: How to display phonetic symbol with correct fonts via WebView ?

First, Download lingoes font file

Android default fonts can not display phonetic symbol.
lingoes.ttf can, please download it.

Second, Put lingoes.ttf to assets/font

assets_font_lingoes.ttf

Last, Add "lingoes" font-family in css files under assets

 @font-face {
    font-family: 'lingoes';
    src:url('file:///android_asset/fonts/lingoes.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
} 

Use "lingoes" as font-family for the phonetic symbol content

Android java : How to load html files in assets via WebView?

Android java : How to load html files in assets via WebView?

The base url for html files under the assets of your app is

"file:///android_asset/"

        WebView wv = new WebView(context);
        wv.getSettings().setJavaScriptEnabled(true);
        wv.loadUrl("file:///android_asset/coca/coca_00001_the.html");

Android java : How to copy/move file from assets to absolute path?

    private void moveAssets(String assets_file_path, String absolutePath) throws IOException {
        File wwwFile = new File(absolutePath);
        if (wwwFile.exists())
            return;
        InputStream is = activity.getAssets().open(assets_file_path);
        byte[] buffer = new byte[is.available()];
        is.read(buffer);
        is.close();
        wwwFile.createNewFile();
        FileOutputStream os = new FileOutputStream(wwwFile);
        os.write(buffer);
        os.close();
    }

Android java: How to orientation activity layout automatically ?

Add ~android:screenOrientation="fullSensor"~ to the activity

 AndroidManifest.xml activity android:name=".MainActivity"             android:screenOrientation="fullSensor" 

shell bash scripts : check process existed or not, if not existed then restart it

Put below scripts in your ~/.bash_profile or ~/.bashrc
It will auto run "unison" process if not running yet
when you open a new bash shell every time.
Change the process name "unison" for your case. :)
auto_unison() {
    u=`ps aux | grep unison | grep -v grep | wc -l`
    if [ $u -eq 0 ]
    then
        unison > /dev/null 2>&1 &
    fi
}
auto_unison

Android how to detect/register language/locale change listener/receiver

The easy way is to register a BroadcastReceiver for Intent.ACTION_LOCALE_CHANGED.

Example: change your ViewModel data when language/locale changed.

public class QASViewModel extends ViewModel {
    @SuppressLint("StaticFieldLeak")
    private final FragmentActivity activity;

    public QASViewModel(@NonNull FragmentActivity activity) {
        this.activity = activity;
        setLangReceiver();
    }

    private void setLangReceiver() {
        final QASViewModel qasViewModel = this;
        final BroadcastReceiver langReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // do action when language change
            }
        };
        activity.getApplicationContext().registerReceiver(langReceiver,
                new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
    }
}

Android ViewModel with ArgsConstructor via Custom ViewModelFactory

Android ViewModel is very useful.
However ViewModel has no args constructor by default.

Typical usage of ViewModel looks like:

public class UserModel extends ViewModel {
} 
final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class);

Let's look the definition of ViewModelProviders.of method.

    /**
     * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given Activity
     * is alive. More detailed explanation is in {@link ViewModel}.
     * 

* It uses the given {@link Factory} to instantiate new ViewModels. * * @param activity an activity, in whose scope ViewModels should be retained * @param factory a {@code Factory} to instantiate new ViewModels * @return a ViewModelProvider instance */ @NonNull @MainThread public static ViewModelProvider of(@NonNull FragmentActivity activity, @Nullable Factory factory) {

Have you found it? We can pass a Factory to create the ViewModel.
Implement your own Factory then you can have args constructor for your ViewModel.

Here we set up a ViewModel with 1 argument construcgtor.
Example code:

    public QASViewModel(@NonNull FragmentActivity activity) {
        this.activity = activity;
    }
    
QASViewModel qasViewModel = ViewModelProviders.of(getActivity(),
                new QASViewModelFactory(getActivity())).get(QASViewModel.class);
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import java.lang.reflect.InvocationTargetException;

public class QASViewModelFactory extends ViewModelProvider.NewInstanceFactory {

    private final FragmentActivity activity;

    /**
     * Creates a {@code AndroidViewModelFactory}
     *
     * @param activity an AssetManager to pass in {@link QASViewModel}
     */
    public QASViewModelFactory(@NonNull FragmentActivity activity) {
        this.activity = activity;
    }

    @NonNull
    @Override
    public  T create(@NonNull Class modelClass) {
        if (QASViewModel.class.isAssignableFrom(modelClass)) {
            try {
                return modelClass.getConstructor(FragmentActivity.class).newInstance(activity);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (InstantiationException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            }
        }
        return super.create(modelClass);
    }
}

How to convert UTC Date Time String to Java object and compare it ?

Use java.time.Instant;

import java.time.Instant;

Instant instantStart = Instant.parse("20200229T12:00:00Z");
Instant instantEnd = Instant.parse("20200329T12:00:00Z");
Instant instantNow = Instant.now();

return instantNow.isAfter(instantStart) &&  
       instantNow.isBefore(instantEnd);

How to convert json array to java Object

Use com.amazonaws.util.json.Jackson
import com.amazonaws.util.json.Jackson;
import java.util.ArrayList;
import lombok.Data;

@Data
class DeviceList {
  private ArrayList<String> devices;
}

DeviceList deviceList = Jackson.fromJsonString(
    "{\"devices\":[\"Mobile\", \"Desktop\"]}", 
    DeviceList.class);

Java Spring Bean constructor how to get call stack, backtrace

Easy wasy to print Java call stack or backtrace:
Implement a function and throw an Exception.
Call the function in the place you want to know its backtrace or callstack
And Catch the Exception then
Call Exception.getStackTrace
class MyService {

    public static void f() throws Exception {
        throw new Exception();
    }

    void forTest() {
        try {
            f();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Via this solution, we can get Bean constructor call stack easily.

[tomcat:launchProperties]       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[tomcat:launchProperties]       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[tomcat:launchProperties]       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[tomcat:launchProperties]       at java.lang.reflect.Method.invoke(Method.java:498)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1178)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1072)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
[tomcat:launchProperties]       at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1136)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
[tomcat:launchProperties]       at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583)
[tomcat:launchProperties]       at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
[tomcat:launchProperties]       at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:364)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1269)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
[tomcat:launchProperties]       at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
[tomcat:launchProperties]       at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
[tomcat:launchProperties]       at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
[tomcat:launchProperties]       at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
[tomcat:launchProperties]       at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
[tomcat:launchProperties]       at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
[tomcat:launchProperties]       at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4851)
[tomcat:launchProperties]       at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
[tomcat:launchProperties]       at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
[tomcat:launchProperties]       at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
[tomcat:launchProperties]       at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
[tomcat:launchProperties]       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[tomcat:launchProperties]       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[tomcat:launchProperties]       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[tomcat:launchProperties]       at java.lang.Thread.run(Thread.java:748)

How to use @Mock @InjectMocks

class MyService {
    private UserDao userDao;
}

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;

public class MyServiceTest {

    @InjectMocks
    private MyService myService;

    @Mock
    private UserDao userDao;
    
    @Before
    public void setUp() {
        myService = new MyService();
    }
}

Cannot mock/spy class java.lang.String Mockito cannot mock/spy following: - final classes - anonymous classes - primitive types

org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class java.lang.String
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl$1.withBefores(JUnit45AndHigherRunnerImpl.java:27)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)

In case you have to mock String, perhaps you can add a function only visible for testing via
import com.google.common.annotations.VisibleForTesting;
And in this function, mock the String type's value.
For Example:
class MyService {
    
    private String name = "myservice";

    @VisibleForTesting
    void forTest(String mockName) {
        this.name = mockName;
    }
}

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;

public class MyServiceTest {

    private MyService myService;

    @Before
    public void setUp() {
        myService = new MyService();
        myService.forTest("mockName");
    }
}

How to increase terminal window buffer in IntelliJ

Command + Shift + A or Ctrl + Shift + A
Type registry, click "Registry..."
registry...

Increase the "terminal.buffer.max.lines.count" to 100000 or any number you want, the default is 1000.
terminal.buffer.max.lines.count

make vim like source insight, a effective c/c++ ide

IDE

ide3.gif

setup latest vim

git clone https://github.com/vim/vim.git cd vim/src ./configure --enable-cscope --enable-terminal make sudo make install 

https://www.vim.org/git.php

use universal ctags

git clone https://github.com/universal-ctags/ctags.git cd ctags ./autogen.sh ./configure make sudo make instahttps://www.tamacom.com/global/global-6.6.3.tar.gzll 

setup gnu tags

wget https://www.tamacom.com/global/global-6.6.3.tar.gz tar -xvf global-6.6.3.tar.gz cd global-6.6.3 sh reconf.sh  sudo apt install ncurses-dev ./configure --with-universal-ctags=/usr/local/bin/ctags  make  sudo make install 

https://www.tamacom.com/global/global-6.6.3.tar.gz
http://www.gnu.org/software/global/download.html

install gtags as vim plugin

cp gtags.vim ~/.vim/plugin/ cp gtags-cscope.vim ~/.vim/plugin/ 

config gtags as cscope in ~/.vimrc

" gtags configure " To use the default key/mouse mapping: let GtagsCscope_Auto_Map = 1 " To ignore letter case when searching: let GtagsCscope_Ignore_Case = 1 " To use absolute path name: let GtagsCscope_Absolute_Path = 1 " To deterring interruption: let GtagsCscope_Keep_Alive = 1 " If you hope auto loading: let GtagsCscope_Auto_Load = 1 let GtagsCscope_Quiet = 1 " To use 'vim -t ', ':tag' and '<C-]>' set cscopetag let Gtags_Auto_Map = 1 " output cscope result to quickfix  set cscopequickfix=s-,g-,c-,d-,i-,t-,e-,f-,-a " open quickfix window if needx autocmd QuickFixCmdPost [^l]* nested botright cwindow  :nmap \s :cs find s <C-R>=expand("<cword>")<CR><CR> :nmap \a :cs find a <C-R>=expand("<cword>")<CR><CR> :nmap \d :cs find d <C-R>=expand("<cword>")<CR><CR> :nmap \g :cs find g <C-R>=expand("<cword>")<CR><CR> :nmap \i :cs find i <C-R>=expand("<cword>")<CR><CR> :nmap \c :cs find c <C-R>=expand("<cword>")<CR><CR> :nmap \e :cs find e <C-R>=expand("<cword>")<CR><CR> :nmap \t :cs find t <C-R>=expand("<cword>")<CR><CR> :nmap \f :cs find f <C-R>=expand("<cword>")<CR><CR> 

Usage:

cscope commands: add  : Add a new database             (Usage: add file|dir [pre-path] [flags]) find : Query for a pattern            (Usage: find a|c|d|e|f|g|i|s|t name)        a: Find assignments to this symbol        c: Find functions calling this function        d: Find functions called by this function        e: Find this egrep pattern        f: Find this file        g: Find this definition        i: Find files #including this file        s: Find this C symbol        t: Find this text string help : Show this message              (Usage: help) kill : Kill a connection              (Usage: kill #) reset: Reinit all connections         (Usage: reset) show : Show connections               (Usage: show) 

Normal Key Map:
Press \a means "cs f a $cname"
Press \s means "cs f s $cname"
Press \t means "cs f t $cname"
Press \e means "cs f e $cname"
Press \c means "cs f c $cname"
Press \d means "cs f d $cname"
Press \i means "cs f i $cname"
Press \g means "cs f g $cname"
Press \f means "cs f f $cname"

install taglist

unzip taglist_46.zip  Archive:  taglist_46.zip   inflating: plugin/taglist.vim         inflating: doc/taglist.txt          cp plugin/taglist.vim ~/.vim/plugin/ cp doc/taglist.txt ~/.vim/doc/ 

https://www.vim.org/scripts/script.php?script_id=273

configure taglist vim plugin

"taglist settings let Tlist_Inc_Winwidth=0 let Tlist_Use_Right_Window=1 let Tlist_File_Fold_Auto_Close=1 let Tlist_Exit_OnlyWindow=1 let Tlist_Auto_Open=1 :nmap <F8> :TlistToggle<CR> function! g:TlistFocus()   let save_winnr = winnr()     let winnum = bufwinnr("__Tag_List__")       if winnum == -1         :TlistToggle         let winnum = bufwinnr("__Tag_List__")       endif     if winnum != -1       if save_winnr != winnum         exe winnum . 'wincmd w'       endif   endif endfunction "focus to Tag list window via CTL command command! -nargs=0 -bar CTL call g:TlistFocus()     

Usage: Press F8 to toggle taglist

install vim-airline

git clone https://github.com/vim-airline/vim-airline ~/.vim/pack/dist/start/vim-airline 

https://github.com/vim-airline/vim-airline

install fzf.vim

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf ~/.fzf/install 

~/.vimrc

" If installed using git set rtp+=~/.fzf 

.vimrc

set nocompatible set backspace=indent,eol,start syntax on syntax enable filetype plugin indent on set autoread set showmatch set hlsearch set incsearch set ignorecase set smartcase set encoding=utf-8 set termencoding=utf-8 set fileencodings=utf-8,gb2312,gbk,gb18030 set tabstop=4 set shiftwidth=4 set expandtab set softtabstop=4 set autoindent set smartindent set ruler set paste  "gtags settings set cscopetag let GtagsCscope_Auto_Load = 1 let CtagsCscope_Auto_Map = 1 let GtagsCscope_Quiet = 1 set cscopequickfix=s-,g-,d-,c-,t-,e-,f-,i-  "open quickfix window if needed autocmd QuickFixCmdPost [^l]* nested botright cwindow  "key maps for gtags "find : Query for a pattern            (Usage: find a|c|d|e|f|g|i|s|t name) "       a: Find assignments to this symbol "       c: Find functions calling this function "       d: Find functions called by this function "       e: Find this egrep pattern "       f: Find this file "       g: Find this definition "       i: Find files #including this file "       s: Find this C symbol "       t: Find this text string :nmap \a :cs find a <C-R>=expand("<cword>")<CR><CR> :nmap \c :cs find c <C-R>=expand("<cword>")<CR><CR> :nmap \d :cs find d <C-R>=expand("<cword>")<CR><CR> :nmap \e :cs find e <C-R>=expand("<cword>")<CR><CR> :nmap \f :cs find f <C-R>=expand("<cword>")<CR><CR> :nmap \g :cs find g <C-R>=expand("<cword>")<CR><CR> :nmap \i :cs find i <C-R>=expand("<cword>")<CR><CR> :nmap \s :cs find s <C-R>=expand("<cword>")<CR><CR> :nmap \t :cs find t <C-R>=expand("<cword>")<CR><CR>  "taglist settings let Tlist_Inc_Winwidth=0 let Tlist_Use_Right_Window=1 let Tlist_File_Fold_Auto_Close=1 let Tlist_Exit_OnlyWindow=1 let Tlist_Auto_Open=1  :nmap <F8> :TlistToggle<CR> function! g:TlistFocus()   let save_winnr = winnr()   let winnum = bufwinnr("__Tag_List__")   if winnum == -1     :TlistToggle     let winnum = bufwinnr("__Tag_List__")   endif   if winnum != -1       if save_winnr != winnum         exe winnum . 'wincmd w'       endif   endif endfunction "focus to Tag list window via CTL command command! -nargs=0 -bar CTL call g:TlistFocus()  "lightline settings set laststatus=2 if !has('gui_running')   set t_Co=256 endif  "ale settings let g:ale_completion_enabled = 1  "multiple-cursor settings let g:multi_cursor_use_default_mapping=0 let g:multi_cursor_start_word_key      = '<C-n>' let g:multi_cursor_select_all_word_key = '<C-a>' let g:multi_cursor_start_key           = 'g<C-n>' let g:multi_cursor_select_all_key      = 'g<C-a>' let g:multi_cursor_next_key            = '<C-n>' let g:multi_cursor_prev_key            = '<C-N>' let g:multi_cursor_skip_key            = '<C-x>' let g:multi_cursor_quit_key            = '<Esc>'  "tag preview configure autocmd FileType qf nnoremap <silent><buffer> p :PreviewQuickfix<CR> autocmd FileType qf nnoremap <silent><buffer> P :PreviewClose<CR>  "fzf configure set rtp+=~/.fzf  " This is the default extra key bindings let g:fzf_action = {   \ 'ctrl-t': 'tab split',   \ 'ctrl-x': 'split',   \ 'ctrl-v': 'vsplit' }  " Default fzf layout " - down / up / left / right let g:fzf_layout = { 'left': '~100%' }  " Customize fzf colors to match your color scheme let g:fzf_colors = \ { 'fg':      ['fg', 'Normal'],   \ 'bg':      ['bg', 'Normal'],   \ 'hl':      ['fg', 'Comment'],   \ 'fg+':     ['fg', 'CursorLine', 'CursorColumn', 'Normal'],   \ 'bg+':     ['bg', 'CursorLine', 'CursorColumn'],   \ 'hl+':     ['fg', 'Statement'],   \ 'info':    ['fg', 'PreProc'],   \ 'border':  ['fg', 'Ignore'],   \ 'prompt':  ['fg', 'Conditional'],   \ 'pointer': ['fg', 'Exception'],   \ 'marker':  ['fg', 'Keyword'],   \ 'spinner': ['fg', 'Label'],   \ 'header':  ['fg', 'Comment'] }  " Enable per-command history. " CTRL-N and CTRL-P will be automatically bound to next-history and " previous-history instead of down and up. If you don't like the change, " explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS. let g:fzf_history_dir = '~/.local/share/fzf-history'  " [Buffers] Jump to the existing window if possible let g:fzf_buffers_jump = 1  " [[B]Commits] Customize the options used by 'git log': let g:fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"'  " [Tags] Command to generate tags file let g:fzf_tags_command = 'gtags'  " [Commands] --expect expression for directly executing the command let g:fzf_commands_expect = 'alt-enter,ctrl-x'  " Mapping selecting mappings nmap <leader><tab> <plug>(fzf-maps-n) xmap <leader><tab> <plug>(fzf-maps-x) omap <leader><tab> <plug>(fzf-maps-o)  " Insert mode completion imap <c-x><c-k> <plug>(fzf-complete-word) imap <c-x><c-f> <plug>(fzf-complete-path) imap <c-x><c-j> <plug>(fzf-complete-file-ag) imap <c-x><c-l> <plug>(fzf-complete-line)  " Advanced customization using autoload functions inoremap <expr> <c-x><c-k> fzf#vim#complete#word({'left': '15%'})  let g:fzf_files_options =   \ '--preview "(coderay {} || less {}) 2> /dev/null | head -'.&lines.'"'  nmap <C-p> :Files<CR> nmap <C-e> :Buffers<CR>  " press s in qf window to open tag in new split window autocmd FileType qf nnoremap <silent><buffer> s <Enter><C-W>s " press v in qf window to open tag in new vertical split window autocmd FileType qf nnoremap <silent><buffer> v <Enter><C-W>v " press t in qf window to open tag in new tab autocmd FileType qf nnoremap <silent><buffer> t <Enter><C-W>T 

Summary

replace .vimrc and .vim with below repo
https://github.com/lengerrong/ervim.git

nginx : set up http/https conf for your server(Ghost)

Let me use cluster.errong.win as a example.
All you need to do is replace the server name and port.
All reqest to cluster.errong.win will be proxyed by http://127.0.0.1:6666

http conf

server {
    listen 80;
    listen [::]:80;

    server_name cluster.errong.win;
    root /home/errong_leng/www/cluster/system/nginx-root;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:6666;
        
    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

enable http server to nginx

ln -sf /home/errong_leng/www/cluster/system/files/cluster.errong.win.conf /etc/nginx/sites-available/cluster.errong.win.conf
ln -sf /etc/nginx/sites-available/cluster.errong.win.conf
/etc/nginx/sites-enabled/cluster.errong.win.conf

Use Let's Encrypt

Let's Encrypt is a free, automated, and open Certificate Authority.
/etc/letsencrypt/acme.sh --issue --home /etc/letsencrypt --domain cluster.errong.win --webroot /home/errong_leng/www/cluster/system/nginx-root --reloadcmd "nginx -s reload" --accountemail errong.leng@gmail.com

https conf

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name cluster.errong.win;
    root /home/errong_leng/www/cluster/system/nginx-root;

    ssl_certificate /etc/letsencrypt/cluster.errong.win/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/cluster.errong.win/cluster.errong.win.key;
    include /etc/nginx/snippets/ssl-params.conf;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:6666;
        
    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

enable https server to nginx

ln -sf /home/errong_leng/www/cluster/system/files/cluster.errong.win-ssl.conf /etc/nginx/sites-available/cluster.errong.win-ssl.conf
ln -sf /etc/nginx/sites-available/cluster.errong.win-ssl.conf
/etc/nginx/sites-enabled/cluster.errong.win-ssl.conf

restart nginx service

service nginx restart

react-native : navigate/load url via WebView

No Image, No Truth

webview-load

use WebView component in reactnative.

var {   ....,   WebView, } = React; 

initial state give a default url

getInitialState: function() {  return {   url: '', // or default url  }; }, 

render with state url

<WebView ....your styles, properties   url={this.state.url} /> 

Navigate/load codes

load() {  this.setState({url:'http://google.com'}); } 

Full Sample Codes

import React, { Component } from 'react';
import {
Button,
Modal,
Image,
Keyboard,
NativeModules,
Platform,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
WebView,
} from 'react-native';

const { WeChat } = NativeModules;

const SHARE_TO_WXTIMELINE = 0;
const SHARE_TO_WXSESSION = 1;
const webview = "webview";
const HOME_URL = "https://errong.win";

export default class App extends Component<{}> {

componentWillMount () {
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {this.keyboardDidHide()});
}

componentWillUnmount () {
this.keyboardDidHideListener.remove();
}

keyboardDidHide () {
console.log( this.urlText );
if (this.urlText != null) {
this.setState({url:this.urlText});
}
}

constructor(props) {
super(props);
this.state = {shareModalVisible : false, url : HOME_URL, urlBarVisible : true};
}

setShareModalVisible(visible) {
this.setState({shareModalVisible : visible});
}

onShare(scene) {
this.setShareModalVisible(false);
this.scene = scene;
if (this.shareMsg == null)
return;
if (WeChat.shareToTimeline)
WeChat.shareToTimeline(this.shareMsg, this.scene, null);
}

onWebViewMessage(event) {
console.warn(event.nativeEvent.data);
let msg;
try {
msg = JSON.parse(event.nativeEvent.data);
} catch (err) {
console.warn(err);
return;
}
if (msg.id == "ABSTRACT_FETCHED")
this.shareMsg = msg;
}

genAbstractJS() {
const genAbstractFunction = function() {
try {
let title;
let description;
let imageUrl;
let msg;
let n = document.querySelector('head title');
if (n)
title = n.innerText;
n = document.querySelector('p');
if (n)
description = n.innerText;
n = document.querySelector('p img');
if (n)
imageUrl = n.src;
if (description && imageUrl) {
msg = { 'id' : 'ABSTRACT_FETCHED',
'type' : 'textimage',
'description' : description,
'imageUrl': imageUrl
};
} else {
msg = { 'id' : 'ABSTRACT_FETCHED',
'type' : 'news',
'webpageUrl' : window.location.href
};
}
window.postMessage(JSON.stringify(msg), "*");
} catch (err) {
console.warn(err);
}
}
let js = "(" + String(genAbstractFunction) + ")();";
console.log(js);
return js;
}

onLoadEnd() {
this.refs[webview].injectJavaScript(this.genAbstractJS());
}

onUrlBar() {
}

renderUrlBar() {
if (this.state.urlBarVisible) {
return (
<TouchableOpacity style={styles.urlbar} onPress={() => {this.onUrlBar()}}>
<TextInput
style={styles.urlentry}
placeholder="search or input url"
onChangeText={(text) => {this.urlText = text}}
/>

)
} else {
return null;
}
}

render() {
return (

{this.renderUrlBar()}
<WebView
ref={webview}
style={{flex:1}}
javaScriptEnabled={true}
onMessage={(event) => {this.onWebViewMessage(event)}}
onLoadEnd={this.onLoadEnd.bind(this)}
source={{uri:this.state.url}}
/>
<Button
onPress={() => {this.setShareModalVisible(true)}}
title="Share"
color="#841584"
accessibilityLabel="Social Share"
/>



<TouchableOpacity style={styles.sharebutton} onPress={() => {this.onShare(SHARE_TO_WXTIMELINE)}}>
<Image
source={require('./res/img/wxtimeline.png')}
/>

<TouchableOpacity style={styles.sharebutton} onPress={() => {this.onShare(SHARE_TO_WXSESSION)}}>
<Image
source={require("./res/img/wxsession.png")}
/>





);
}
}

const styles = StyleSheet.create({
urlbar:{
backgroundColor:'#fafad2',
borderTopLeftRadius:4,
borderTopRightRadius:4,
borderBottomLeftRadius:4,
borderBottomRightRadius:4,
boderColor : '#C0C0C0',
borderWidth: 1
},
urlentry:{
height: 40
},
sgc:{
height:100,
width:300,
borderTopLeftRadius:10,
borderTopRightRadius:10,
borderBottomLeftRadius:10,
borderBottomRightRadius:10,
alignSelf: 'center',
top:400,
backgroundColor:'#fafad2'
},
sharegroup: {
flex:1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-around',
},
sharebutton: {
width:64,
height:64
}
})

react-native : Modal example, share to WeChat

Refer

https://facebook.github.io/react-native/docs/modal.html

No Image, No Truth

modal-share

Full Codes

import React, { Component } from 'react'; import {     Button, 	Modal,     Image,     Keyboard,     NativeModules,     Platform,     StyleSheet,     Text,     TextInput,     TouchableOpacity,     View,     WebView, } from 'react-native';  const { WeChat } = NativeModules;  const SHARE_TO_WXTIMELINE = 0; const SHARE_TO_WXSESSION = 1; const webview = "webview"; const HOME_URL = "https://errong.win";  export default class App extends Component<{}> {    componentWillMount () {     this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {this.keyboardDidHide()});   }    componentWillUnmount () {     this.keyboardDidHideListener.remove();   }    keyboardDidHide () {     console.log( this.urlText );     if (this.urlText != null) {       this.setState({url:this.urlText});     }   }    constructor(props) {     super(props);     this.state = {shareModalVisible : false, url : HOME_URL, urlBarVisible : true};   }    setShareModalVisible(visible) {     this.setState({shareModalVisible : visible});   }    onShare(scene) {     this.setShareModalVisible(false); 	this.scene = scene;     if (this.shareMsg == null)       return;     if (WeChat.shareToTimeline)       WeChat.shareToTimeline(this.shareMsg, this.scene, null);   }    onWebViewMessage(event) {     console.warn(event.nativeEvent.data);     let msg;     try {       msg = JSON.parse(event.nativeEvent.data);     } catch (err) {       console.warn(err);       return;     }     if (msg.id == "ABSTRACT_FETCHED")       this.shareMsg = msg;   }    genAbstractJS() {     const genAbstractFunction = function() {       try {         let title;         let description;         let imageUrl;         let msg;         let n = document.querySelector('head title');         if (n)             title = n.innerText;         n = document.querySelector('p');         if (n)             description = n.innerText;         n = document.querySelector('p img');         if (n)             imageUrl = n.src;         if (description && imageUrl) {             msg = { 'id' : 'ABSTRACT_FETCHED',                     'type' : 'textimage',                     'description' : description,                     'imageUrl': imageUrl                   };         } else {            msg = { 'id' : 'ABSTRACT_FETCHED',                    'type' : 'news',                    'webpageUrl' : window.location.href                  };         }         window.postMessage(JSON.stringify(msg), "*");       } catch (err) {         console.warn(err);       }     }     let js = "(" + String(genAbstractFunction) + ")();";     console.log(js);     return js;   }    onLoadEnd() {     this.refs[webview].injectJavaScript(this.genAbstractJS());   }    onUrlBar() {   }    renderUrlBar() {     if (this.state.urlBarVisible) {       return (         <TouchableOpacity style={styles.urlbar} onPress={() => {this.onUrlBar()}}>           <TextInput             style={styles.urlentry}             placeholder="search or input url"             onChangeText={(text) => {this.urlText = text}}           />         </TouchableOpacity>       )     } else {       return null;     }   }    render() {     return (     <View style={{flex:1}}>       {this.renderUrlBar()}       <WebView         ref={webview}         style={{flex:1}}         javaScriptEnabled={true}         onMessage={(event) => {this.onWebViewMessage(event)}}         onLoadEnd={this.onLoadEnd.bind(this)}         source={{uri:this.state.url}}       />       <Button         onPress={() => {this.setShareModalVisible(true)}}         title="Share"         color="#841584"         accessibilityLabel="Social Share"       /> 	  <Modal 		transparent={true} 		visible={this.state.shareModalVisible} 		> 		<View style={styles.sgc}>           <View style={styles.sharegroup}>             <TouchableOpacity style={styles.sharebutton} onPress={() => {this.onShare(SHARE_TO_WXTIMELINE)}}>               <Image                 source={require('./res/img/wxtimeline.png')}               />             </TouchableOpacity>             <TouchableOpacity style={styles.sharebutton} onPress={() => {this.onShare(SHARE_TO_WXSESSION)}}>               <Image                 source={require("./res/img/wxsession.png")}               />             </TouchableOpacity>           </View> 		</View> 	  </Modal>     </View>     );   } }  const styles = StyleSheet.create({   urlbar:{   	backgroundColor:'#fafad2',     borderTopLeftRadius:4,     borderTopRightRadius:4,     borderBottomLeftRadius:4,     borderBottomRightRadius:4,     boderColor : '#C0C0C0',     borderWidth: 1   },   urlentry:{     height: 40   },   sgc:{   	height:100,     width:300,     borderTopLeftRadius:10,     borderTopRightRadius:10,     borderBottomLeftRadius:10,     borderBottomRightRadius:10,     alignSelf: 'center',   	top:400,   	backgroundColor:'#fafad2'   },   sharegroup: {   	flex:1, 	flexDirection: 'row',   	alignItems: 'center',   	justifyContent: 'space-around',   },   sharebutton: {     width:64,     height:64   } }) 

react-native : How to create Image Button

Solution

Use TouchableOpacity, Image and Styles.

Key codes

import React, { Component } from 'react'; import {         Image,     StyleSheet,        TouchableOpacity, } from 'react-native';  <TouchableOpacity     style={styles.sharebutton}     onPress={() => {this.onShare(SHARE_TO_WXTIMELINE)}} >     <Image         source={require('./res/img/wxtimeline.png')}     /> </TouchableOpacity>          

No Image, No Truth

modal-share
See Full sample codes Share to WeXin via Modal

react-native : Native Modules, name prefix "RCT"works for android too

I tried to export wechat sdk as a native module.
I copied some codes here:
public class WeChatModule extends ReactContextBaseJavaModule implements IWXAPIEventHandler {
  private String appId; 
  public WeChatModule(ReactApplicationContext context) { 
    super(context); 
  @Override     public String getName() { 
    return "RCTWeChat"; 
} 
I used "RCTWeChat" as the module name, I did not know the "RCT" prefix meanings.

ReactContextBaseJavaModule requires that a method called getName is implemented. The purpose of this method is to return the string name of the NativeModule which represents this class in JavaScript.

Then I encountered error in my react-native JS codes.
import {NativeModules} from 'react-native'; const { RCTWeChat } = NativeModules; 
WeChat or NativeModules.RCTWeChat always undefined.

Cause

RCT is a prefix used in react native, it will be removed when exported to JS.
React Native uses RCT as a prefix. In order to avoid name collisions, we recommend using a three-letter prefix other than RCT in your own classes.

Solution

The correct JS codes:
const { WeChat } = NativeModules;

react-native run-android : No connected devices!

  • What went wrong:
    Execution failed for task ':app:installDebug'.

com.android.builder.testing.api.DeviceException: No connected devices!

Cause

ADB driver is not ready

Solution

Install correct driver
adb

fixed: embedded-redis: Unable to run on macOS Sonoma

Issue you might see below error while trying to run embedded-redis for your testing on your macOS after you upgrade to Sonoma. java.la...