From 1ea247829af8a7e0addbdde0f2ad7bd91041e4cb Mon Sep 17 00:00:00 2001 From: tateisu Date: Wed, 23 Aug 2017 18:43:20 +0900 Subject: [PATCH] =?UTF-8?q?v1.2.2=20-=20=E3=83=AA=E3=83=A2=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=81=8B=E3=82=89=E6=9D=A5=E3=81=9F=E3=83=88=E3=82=A5?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=81=AB=E5=AF=BE=E3=81=97=E3=81=A6=E3=80=8C?= =?UTF-8?q?=E5=88=A5=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=B3=E3=83=88=E3=81=A7?= =?UTF-8?q?=E4=BC=9A=E8=A9=B1=E3=81=AE=E6=B5=81=E3=82=8C=E3=80=8D=E3=82=92?= =?UTF-8?q?=E9=96=8B=E3=81=84=E3=81=9F=E6=99=82=E3=81=AB=E7=99=BA=E8=A8=80?= =?UTF-8?q?=E5=85=83=E3=82=BF=E3=83=B3=E3=82=B9=E3=81=AE=E7=96=91=E4=BC=BC?= =?UTF-8?q?=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=B3=E3=83=88=E3=82=92=E9=81=B8?= =?UTF-8?q?=E3=81=B9=E3=82=8B=20-=20=E7=9B=B8=E5=AF=BE=E6=99=82=E5=88=BB?= =?UTF-8?q?=E8=A1=A8=E8=A8=98=E3=81=AE=E6=97=A5=E6=95=B0=E3=81=AE=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=8C=E9=96=93=E9=81=95=E3=81=A3=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=81=9F=E3=83=90=E3=82=B0=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/jp/juggler/subwaytooter/ActMain.java | 206 ++++++++++++------ .../subwaytooter/api/TootApiClient.java | 61 ++++-- .../subwaytooter/api/entity/TootStatus.java | 6 +- app/src/main/res/values-fr/strings.xml | 12 +- app/src/main/res/values-ja/strings.xml | 14 +- app/src/main/res/values/strings.xml | 16 +- 6 files changed, 209 insertions(+), 106 deletions(-) diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActMain.java b/app/src/main/java/jp/juggler/subwaytooter/ActMain.java index 533450c2..9507fc04 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ActMain.java +++ b/app/src/main/java/jp/juggler/subwaytooter/ActMain.java @@ -87,8 +87,10 @@ import jp.juggler.subwaytooter.util.Utils; import jp.juggler.subwaytooter.view.ColumnStripLinearLayout; import jp.juggler.subwaytooter.view.GravitySnapHelper; import jp.juggler.subwaytooter.view.MyEditText; +import okhttp3.Call; import okhttp3.Request; import okhttp3.RequestBody; +import okhttp3.Response; public class ActMain extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, View.OnClickListener, ViewPager.OnPageChangeListener, Column.Callback, DrawerLayout.DrawerListener @@ -2616,6 +2618,8 @@ public class ActMain extends AppCompatActivity } } + static final Pattern reUriOStatusToot = Pattern.compile( "tag:([^,]*),[^:]*:objectId=(\\d+):objectType=Status" ,Pattern.CASE_INSENSITIVE); + public void openStatusOtherInstance( int pos, @NonNull SavedAccount access_info, @NonNull TootStatusLike status ){ if( status.account == null ){ // アカウント情報がないと出来ないことがある @@ -2625,18 +2629,36 @@ public class ActMain extends AppCompatActivity , status.host_original, status.id , null, - 1L ); - }else if( status.host_original.equals( status.host_access ) ){ - // TLアカウントのホストとトゥートのアカウントのホストが同じ場合 - openStatusOtherInstance( pos, access_info, status.url - , status.host_original, status.id - , null, - 1L - ); - }else{ - // TLアカウントのホストとトゥートのアカウントのホストが異なる場合 - openStatusOtherInstance( pos, access_info, status.url - , null, - 1L - , status.host_access, status.id - ); + }else if( status instanceof TootStatus ){ + TootStatus ts = (TootStatus)status; + if( status.host_original.equals( status.host_access ) ){ + // TLアカウントのホストとトゥートのアカウントのホストが同じ場合 + openStatusOtherInstance( pos, access_info, status.url + , status.host_original, status.id + , null, - 1L + ); + }else{ + // TLアカウントのホストとトゥートのアカウントのホストが異なる場合 + + long status_id_original = -1L; + String host_original = null; + + try{ + // OStatusでフィードされたトゥートの場合、UriにステータスIDが含まれている + Matcher m = reUriOStatusToot.matcher( ts.uri ); + if( m.find() ){ + status_id_original = Long.parseLong( m.group( 2 ), 10 ); + host_original = m.group( 1 ); + } + }catch(Throwable ex){ + log.e(ex,"openStatusOtherInstance: cant parse tag: %s",ts.uri); + } + + openStatusOtherInstance( pos, access_info, status.url + , host_original,status_id_original + , status.host_access, status.id + ); + } } } @@ -2644,64 +2666,41 @@ public class ActMain extends AppCompatActivity final int pos , @Nullable final SavedAccount access_info , @NonNull final String url - , final String host_original, final long status_id_original + , final String host_original_unused, final long status_id_original , final String host_access, final long status_id_access ){ ActionsDialog dialog = new ActionsDialog(); - Uri uri = Uri.parse( url ); - String host_name = uri.getAuthority(); + final String host_original = Uri.parse( url ).getAuthority(); // 選択肢:ブラウザで表示する - dialog.addAction( getString( R.string.open_web_on_host, host_name ), new Runnable() { + dialog.addAction( getString( R.string.open_web_on_host, host_original ), new Runnable() { @Override public void run(){ openChromeTab( pos, access_info, url, true ); } } ); - boolean has_local_account = false; - ArrayList< SavedAccount > account_list = new ArrayList<>(); + ArrayList local_account_list = new ArrayList<>( ); + ArrayList access_account_list = new ArrayList<>( ); + ArrayList other_account_list = new ArrayList<>( ); for( SavedAccount a : SavedAccount.loadAccountList( ActMain.this, log ) ){ + // 疑似アカウントは後でまとめて処理する + if( a.isPseudo() ) continue; if( status_id_original >= 0L && host_original.equalsIgnoreCase( a.host ) ){ // アクセス情報+ステータスID でアクセスできるなら // 同タンスのアカウントならステータスIDの変換なしに表示できる - account_list.add( a ); - has_local_account = true; + local_account_list.add( a ); }else if( status_id_access >= 0L && host_access.equalsIgnoreCase( a.host ) ){ // 既に変換済みのステータスIDがあるなら、そのアカウントでもステータスIDの変換は必要ない - account_list.add( a ); - }else if( ! a.isPseudo() ){ + access_account_list.add( a ); + }else{ // 別タンスでも実アカウントなら検索APIでステータスIDを変換できる - account_list.add( a ); + other_account_list.add(a); } } - // ソートする - Collections.sort( account_list, new Comparator< SavedAccount >() { - @Override public int compare( SavedAccount a, SavedAccount b ){ - return String.CASE_INSENSITIVE_ORDER.compare( AcctColor.getNickname( a.acct ), AcctColor.getNickname( b.acct ) ); - } - } ); - - // ダイアログの選択肢に追加 - for( SavedAccount a : account_list ){ - final SavedAccount _a = a; - - dialog.addAction( getString( R.string.open_in_account, AcctColor.getNickname( a.acct ) ), new Runnable() { - @Override public void run(){ - if( status_id_original >= 0L && host_original.equalsIgnoreCase( _a.host ) ){ - openStatusLocal( pos, _a, status_id_original ); - }else if( status_id_access >= 0L && host_access.equalsIgnoreCase( _a.host ) ){ - openStatusLocal( pos, _a, status_id_access ); - }else if( ! _a.isPseudo() ){ - openStatusRemote( pos, _a, url ); - } - } - } ); - } - - // 同タンスのアカウントがないなら、疑似アカウントを作る選択肢 - if( ! has_local_account ){ + // 同タンスのアカウントがないなら、疑似アカウントで開く選択肢 + if( local_account_list.isEmpty() ){ if( status_id_original >= 0L ){ dialog.addAction( getString( R.string.open_in_pseudo_account, "?@" + host_original ), new Runnable() { @Override public void run(){ @@ -2711,15 +2710,68 @@ public class ActMain extends AppCompatActivity } } } ); - }else if( status_id_access >= 0L ){ - // リモートから流れてきたトゥートを オリジナルのインスタンスの疑似アカウントで開きたい - // しかし疑似アカウントでは検索ができないので、オリジナルのインスタンス上でのステータスIDを知る方法がない + }else{ + dialog.addAction( getString( R.string.open_in_pseudo_account, "?@" + host_original ), new Runnable() { + @Override public void run(){ + SavedAccount sa = addPseudoAccount( host_original ); + if( sa != null ){ + openStatusRemote(pos, sa, url ); + } + } + } ); } } + // ローカルアカウント + Collections.sort( local_account_list, new Comparator< SavedAccount >() { + @Override public int compare( SavedAccount a, SavedAccount b ){ + return String.CASE_INSENSITIVE_ORDER.compare( AcctColor.getNickname( a.acct ), AcctColor.getNickname( b.acct ) ); + } + } ); + for( SavedAccount a : local_account_list ){ + final SavedAccount _a = a; + dialog.addAction( getString( R.string.open_in_account, AcctColor.getNickname( a.acct ) ), new Runnable() { + @Override public void run(){ + openStatusLocal( pos, _a, status_id_original ); + } + } ); + } + + // アクセスしたアカウント + Collections.sort( access_account_list, new Comparator< SavedAccount >() { + @Override public int compare( SavedAccount a, SavedAccount b ){ + return String.CASE_INSENSITIVE_ORDER.compare( AcctColor.getNickname( a.acct ), AcctColor.getNickname( b.acct ) ); + } + } ); + for( SavedAccount a : access_account_list ){ + final SavedAccount _a = a; + dialog.addAction( getString( R.string.open_in_account, AcctColor.getNickname( a.acct ) ), new Runnable() { + @Override public void run(){ + openStatusLocal( pos, _a, status_id_access ); + } + } ); + } + + // その他の実アカウント + Collections.sort( other_account_list, new Comparator< SavedAccount >() { + @Override public int compare( SavedAccount a, SavedAccount b ){ + return String.CASE_INSENSITIVE_ORDER.compare( AcctColor.getNickname( a.acct ), AcctColor.getNickname( b.acct ) ); + } + } ); + for( SavedAccount a : other_account_list ){ + final SavedAccount _a = a; + dialog.addAction( getString( R.string.open_in_account, AcctColor.getNickname( a.acct ) ), new Runnable() { + @Override public void run(){ + openStatusRemote( pos, _a, url ); + } + } ); + } + dialog.show( this, getString( R.string.open_status_from ) ); } + static final Pattern reDetailedStatusTime = Pattern.compile( "]*?\\bdetailed-status__datetime\\b[^>]*href=\"https://[^/]+/@[^/]+/(\\d+)\""); + public void openStatusRemote( final int pos , final SavedAccount access_info @@ -2728,7 +2780,8 @@ public class ActMain extends AppCompatActivity final ProgressDialog progress = new ProgressDialog( this ); final AsyncTask< Void, Void, TootApiResult > task = new AsyncTask< Void, Void, TootApiResult >() { - TootStatus target_status; + + long local_status_id = -1L; @Override protected TootApiResult doInBackground( Void... params ){ TootApiClient client = new TootApiClient( ActMain.this, new TootApiClient.Callback() { @@ -2741,19 +2794,37 @@ public class ActMain extends AppCompatActivity } ); client.setAccount( access_info ); - // 検索APIに他タンスのステータスのURLを投げると、自タンスのステータスを得られる - String path = String.format( Locale.JAPAN, Column.PATH_SEARCH, Uri.encode( remote_status_url ) ); - path = path + "&resolve=1"; - - TootApiResult result = client.request( path ); - if( result != null && result.object != null ){ - TootResults tmp = TootResults.parse( ActMain.this, access_info, result.object ); - if( tmp != null && tmp.statuses != null && ! tmp.statuses.isEmpty() ){ - target_status = tmp.statuses.get( 0 ); - log.d( "status id conversion %s => %s", remote_status_url, target_status.id ); + TootApiResult result; + if( access_info.isPseudo() ){ + result = client.getHttp(remote_status_url); + if( result != null && result.json != null ){ + try{ + Matcher m = reDetailedStatusTime.matcher( result.json ); + if( m.find() ){ + local_status_id = Long.parseLong( m.group(1) ,10); + } + }catch(Throwable ex){ + log.e(ex,"openStatusRemote: can't parse status id from HTML data."); + } + if( local_status_id == -1L ){ + result = new TootApiResult( getString( R.string.status_id_conversion_failed ) ); + } } - if( target_status == null ){ - return new TootApiResult( getString( R.string.status_id_conversion_failed ) ); + }else{ + // 検索APIに他タンスのステータスのURLを投げると、自タンスのステータスを得られる + String path = String.format( Locale.JAPAN, Column.PATH_SEARCH, Uri.encode( remote_status_url ) ); + path = path + "&resolve=1"; + result = client.request( path ); + if( result != null && result.object != null ){ + TootResults tmp = TootResults.parse( ActMain.this, access_info, result.object ); + if( tmp != null && tmp.statuses != null && ! tmp.statuses.isEmpty() ){ + TootStatus status = tmp.statuses.get( 0 ); + local_status_id = status.id; + log.d( "status id conversion %s => %s", remote_status_url, status.id ); + } + if( local_status_id == -1L ){ + result = new TootApiResult( getString( R.string.status_id_conversion_failed ) ); + } } } return result; @@ -2772,8 +2843,8 @@ public class ActMain extends AppCompatActivity } if( result == null ){ // cancelled. - }else if( target_status != null ){ - openStatus( pos, access_info, target_status ); + }else if( local_status_id != -1L ){ + openStatusLocal( pos, access_info, local_status_id ); }else{ Utils.showToast( ActMain.this, true, result.error ); } @@ -2791,6 +2862,7 @@ public class ActMain extends AppCompatActivity progress.show(); task.executeOnExecutor( App1.task_executor ); } + //////////////////////////////////////// // delete notification diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.java b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.java index 1f9b51d3..12fb6419 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.java +++ b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.java @@ -117,7 +117,7 @@ public class TootApiClient { if( callback.isApiCancelled() ) return null; if( ! response.isSuccessful() ){ - return new TootApiResult( instance + ": " +context.getString( R.string.network_error_arg, response ) ); + return new TootApiResult( instance + ": " + context.getString( R.string.network_error_arg, response ) ); } try{ @@ -198,13 +198,13 @@ public class TootApiClient { response = call.execute(); }catch( Throwable ex ){ log.trace( ex ); - return new TootApiResult( instance + ": " +Utils.formatError( ex, context.getResources(), R.string.network_error ) ); + return new TootApiResult( instance + ": " + Utils.formatError( ex, context.getResources(), R.string.network_error ) ); } if( callback.isApiCancelled() ) return null; if( ! response.isSuccessful() ){ - return new TootApiResult( instance + ": " +context.getString( R.string.network_error_arg, response ) ); + return new TootApiResult( instance + ": " + context.getString( R.string.network_error_arg, response ) ); } try{ @@ -231,7 +231,7 @@ public class TootApiClient { } } - public @Nullable TootApiResult authorize1(String client_name){ + public @Nullable TootApiResult authorize1( String client_name ){ JSONObject client_info; @@ -244,7 +244,7 @@ public class TootApiClient { Response response; try{ - if( TextUtils.isEmpty( client_name )){ + if( TextUtils.isEmpty( client_name ) ){ client_name = "SubwayTooter"; } @@ -262,12 +262,12 @@ public class TootApiClient { response = call.execute(); }catch( Throwable ex ){ log.trace( ex ); - return new TootApiResult( instance + ": " +Utils.formatError( ex, context.getResources(), R.string.network_error ) ); + return new TootApiResult( instance + ": " + Utils.formatError( ex, context.getResources(), R.string.network_error ) ); } if( callback.isApiCancelled() ) return null; if( ! response.isSuccessful() ){ - return new TootApiResult( instance + ": " +context.getString( R.string.network_error_arg, response ) ); + return new TootApiResult( instance + ": " + context.getString( R.string.network_error_arg, response ) ); } try{ //noinspection ConstantConditions @@ -311,7 +311,7 @@ public class TootApiClient { return new TootApiResult( browser_url ); } -public @Nullable TootApiResult authorize2( String code ){ + public @Nullable TootApiResult authorize2( String code ){ JSONObject client_info = ClientInfo.load( instance ); if( client_info == null ){ @@ -341,7 +341,7 @@ public @Nullable TootApiResult authorize2( String code ){ response = call.execute(); }catch( Throwable ex ){ log.trace( ex ); - return new TootApiResult( instance + ": " +Utils.formatError( ex, context.getResources(), R.string.network_error ) ); + return new TootApiResult( instance + ": " + Utils.formatError( ex, context.getResources(), R.string.network_error ) ); } if( callback.isApiCancelled() ) return null; @@ -387,7 +387,7 @@ public @Nullable TootApiResult authorize2( String code ){ response = call.execute(); }catch( Throwable ex ){ log.trace( ex ); - return new TootApiResult( instance + ": " +Utils.formatError( ex, context.getResources(), R.string.network_error ) ); + return new TootApiResult( instance + ": " + Utils.formatError( ex, context.getResources(), R.string.network_error ) ); } if( callback.isApiCancelled() ) return null; @@ -430,10 +430,10 @@ public @Nullable TootApiResult authorize2( String code ){ JSONObject token_info; Response response; try{ - + // 指定されたアクセストークンを使って token_info を捏造する - token_info = new JSONObject( ); - token_info.put("access_token",access_token); + token_info = new JSONObject(); + token_info.put( "access_token", access_token ); // 認証されたアカウントのユーザ名を取得する String path = "/api/v1/accounts/verify_credentials"; @@ -449,7 +449,7 @@ public @Nullable TootApiResult authorize2( String code ){ response = call.execute(); }catch( Throwable ex ){ log.trace( ex ); - return new TootApiResult( instance + ": " +Utils.formatError( ex, context.getResources(), R.string.network_error ) ); + return new TootApiResult( instance + ": " + Utils.formatError( ex, context.getResources(), R.string.network_error ) ); } if( callback.isApiCancelled() ) return null; @@ -482,4 +482,35 @@ public @Nullable TootApiResult authorize2( String code ){ } } -} + public TootApiResult getHttp( String url ){ + Response response; + try{ + Request.Builder request_builder = new Request.Builder(); + request_builder.url( url ); + + Call call = ok_http_client.newCall( request_builder.build() ); + + response = call.execute(); + }catch( Throwable ex ){ + log.trace( ex ); + return new TootApiResult( url + ": " + Utils.formatError( ex, context.getResources(), R.string.network_error ) ); + } + + if( callback.isApiCancelled() ) return null; + + if( ! response.isSuccessful() ){ + return new TootApiResult( url + ": " + context.getString( R.string.network_error_arg, response ) ); + } + + try{ + //noinspection ConstantConditions + String body = response.body().string(); + JSONObject data = new JSONObject(); + data.put( "body", body ); + return new TootApiResult( response, null, body, data ); + }catch( Throwable ex ){ + log.trace( ex ); + return new TootApiResult( Utils.formatError( ex, "API data error" ) ); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.java b/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.java index 193de994..b80b014b 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.java +++ b/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.java @@ -198,7 +198,7 @@ public class TootStatus extends TootStatusLike { long delta = now - t; String sign = context.getString( delta > 0 ? R.string.ago : R.string.later ); delta = delta >= 0 ? delta : - delta; - if( delta < 2000L ){ + if( delta < 1000L ){ return context.getString( R.string.time_within_second ); }else if( delta < 60000L ){ int v = (int) ( delta / 1000L ); @@ -209,8 +209,8 @@ public class TootStatus extends TootStatusLike { }else if( delta < 86400000L ){ int v = (int) ( delta / 3600000L ); return context.getString( v > 1 ? R.string.relative_time_hour_2 : R.string.relative_time_hour_1, v, sign ); - }else if( delta < 65 * 86400000L ){ - int v = (int) ( delta / 3600000L ); + }else if( delta < 40 * 86400000L ){ + int v = (int) ( delta / 86400000L ); return context.getString( v > 1 ? R.string.relative_time_day_2 : R.string.relative_time_day_1, v, sign ); } } diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index d98f883d..a414be59 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -358,9 +358,9 @@ Enables speech (URL omitted) Blocked domains - Block whole domain \'%1$s\' - Whole domain \'%1$s\' will be blocked. Are you sure? - Unblock domain \'%1$s\'? + Block whole domain \"%1$s\" + Whole domain \"%1$s\" will be blocked. Are you sure? + Unblock domain \"%1$s\"? TextToSpeech initializing… TextToSpeech initializing failed. status=%1$s @@ -403,7 +403,7 @@ Access token Please input access token. Quote name… - Format of \'Quote name\' (set text that contains %1$s) + Format of \"Quote name\" (set text that contains %1$s) Masquer les favourite Masquer les follow Background image @@ -414,7 +414,7 @@ Enable GIF animation (It wastes the battery very much) (sample)username@instance Show mention as full acct (column reload required) - Remote users\' profile may be inadequate information. You can check more accurate information on the web page. + Remote user\'s profile may be inadequate information. You can check more accurate information on the web page. Public profile Change avatar icon Change header image @@ -425,7 +425,7 @@ E-mail Description Version - %1$s Instance information + Instance information of \"%1$s\" Instance information Missing E-mail app. Show relative timestamps diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index d5d17359..87c7e74c 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -434,9 +434,9 @@ 発言へのアクション - ユーザ \'%1$s\' をブロックします。よろしいですか? + ユーザ \"%1$s\" をブロックします。よろしいですか? - ユーザ \'%1$s\' をミュートします。よろしいですか? + ユーザ \"%1$s\" をミュートします。よろしいですか? この発言を削除します。よろしいですか? @@ -644,10 +644,10 @@ Chrome Custom Tabs を優先的に利用する 読み上げを有効にする (URL略) - \'%1$s\' ドメインをブロック + \"%1$s\" ドメインをブロック ブロックしたドメイン - ドメイン \'%1$s\' 全体をブロックします。よろしいですか? - ドメイン \'%1$s\' のブロックを解除しますか? + ドメイン \"%1$s\" 全体をブロックします。よろしいですか? + ドメイン \"%1$s\" のブロックを解除しますか? TextToSpeechの初期化中… TextToSpeechの初期化に失敗。status=%1$s @@ -690,7 +690,7 @@ アクセストークンを指定する(上級者向け) アクセストークンを入力してください 名前を引用… - \'名前を引用\'のフォーマット ( %1$s を含むテキストを指定する) + \"名前を引用\"のフォーマット ( %1$s を含むテキストを指定する) お気に入りを表示しない フォローを表示しない Acctの文字色 @@ -712,7 +712,7 @@ メールアドレス 説明 バージョン - %1$sのインスタンス情報 + \"%1$s\"のインスタンス情報 インスタンス情報 メールアドレスを共有できるアプリがありません 相対時刻を表示 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8b8d614a..f7aff09d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -219,8 +219,8 @@ Send message Send message from another account Open profile from another account - User \'%1$s\' will be blocked. Are you sure? - User \'%1$s\' will be muted. Are you sure? + User \"%1$s\" will be blocked. Are you sure? + User \"%1$s\" will be muted. Are you sure? This toot will be deleted. Are you sure? Nickname and color (if specified, it\'s shown instead of full acct) Color @@ -354,9 +354,9 @@ Enables speech (URL omitted) Blocked domains - Block whole domain \'%1$s\' - Whole domain \'%1$s\' will be blocked. Are you sure? - Unblock domain \'%1$s\'? + Block whole domain \"%1$s\" + Whole domain \"%1$s\" will be blocked. Are you sure? + Unblock domain \"%1$s\"? TextToSpeech initializing… TextToSpeech initializing failed. status=%1$s TextToSpeech shutdown… @@ -398,7 +398,7 @@ Access token Please input access token. Quote name… - Format of \'Quote name\' (set text that contains %1$s) + Format of \"Quote name\" (set text that contains %1$s) Don\'t show favourite Don\'t show follow Background image @@ -409,7 +409,7 @@ Enable GIF animation (It wastes the battery very much) (sample)username@instance Show mention as full acct (column reload required) - Remote users\' profile may be inadequate information. You can check more accurate information on the web page. + Remote user\'s profile may be inadequate information. You can check more accurate information on the web page. Public profile Change avatar icon Change header image @@ -420,7 +420,7 @@ E-mail Description Version - %1$s Instance information + Instance information of \"%1$s\" Instance information Missing E-mail app. Show relative timestamps