EN

Search
Close this search box.

موستانگ، وحشیِ دوست داشتنی

0 رای

تغییر نام برنامه

برای ios:

وارد پوشه ios در پروژه بشوید و فایل Info.plist را پیدا کنید. کلید <key>CFBundleDisplayName</key> را پیدا کنید و مقدار string آن را به نام اپ دلخواهی تان تغییر دهید.

برای اندروید:

وارد فولدر android در پروژه تان بشوید و فایل android/app/src/main/res/values/strings.xml را پیدا کنید. مقدار تگ <string name="app_name"> را با نام دلخواهی تان تغییر دهید.

 

تغییر لوگو برنامه

برای ios:

فایل آیکون موجود در مسیر ios/{YourAppName}/Images.xcassets/AppIcon.appiconset را با فایل دلخواهی خودتان جایگزین کنید.

برای اندروید:

فایل های آیکون موجود در مسیر android/app/src/main/res/mipmap-* را با فایل های دلخواهی خودتان جایگزین کنید.

0 رای

تغییر نام برنامه

برای ios:

وارد پوشه ios در پروژه بشوید و فایل Info.plist را پیدا کنید. کلید <key>CFBundleDisplayName</key> را پیدا کنید و مقدار string آن را به نام اپ دلخواهی تان تغییر دهید.

برای اندروید:

وارد فولدر android در پروژه تان بشوید و فایل android/app/src/main/res/values/strings.xml را پیدا کنید. مقدار تگ <string name="app_name"> را با نام دلخواهی تان تغییر دهید.

 

تغییر لوگو برنامه

برای ios:

فایل آیکون موجود در مسیر ios/{YourAppName}/Images.xcassets/AppIcon.appiconset را با فایل دلخواهی خودتان جایگزین کنید.

برای اندروید:

فایل های آیکون موجود در مسیر android/app/src/main/res/mipmap-* را با فایل های دلخواهی خودتان جایگزین کنید.

0 رای
در پاسخ به: dropdown در react native

برای پیاده سازی یک لیست dropdown می توانید از کتابخانه react-native-element-dropdown استفاده کنید. با دستور زیر نصبش کنید:

npm install react-native-element-dropdown --save

برای استفاده هم می توانید از مثال زیر الگو بگیرید:

  import React, { useState } from 'react';
  import { StyleSheet } from 'react-native';
  import { Dropdown } from 'react-native-element-dropdown';
  import AntDesign from '@expo/vector-icons/AntDesign';

  const data = [
    { label: 'Item 1', value: '1' },
    { label: 'Item 2', value: '2' },
    { label: 'Item 3', value: '3' },
    { label: 'Item 4', value: '4' },
    { label: 'Item 5', value: '5' },
    { label: 'Item 6', value: '6' },
    { label: 'Item 7', value: '7' },
    { label: 'Item 8', value: '8' },
  ];

  const DropdownComponent = () => {
    const [value, setValue] = useState(null);

    return (
      <Dropdown
        style={styles.dropdown}
        placeholderStyle={styles.placeholderStyle}
        selectedTextStyle={styles.selectedTextStyle}
        inputSearchStyle={styles.inputSearchStyle}
        iconStyle={styles.iconStyle}
        data={data}
        search
        maxHeight={300}
        labelField="label"
        valueField="value"
        placeholder="Select item"
        searchPlaceholder="Search..."
        value={value}
        onChange={item => {
          setValue(item.value);
        }}
        renderLeftIcon={() => (
          <AntDesign style={styles.icon} color="black" name="Safety" size={20} />
        )}
      />
    );
  };

  export default DropdownComponent;

  const styles = StyleSheet.create({
    dropdown: {
      margin: 16,
      height: 50,
      borderBottomColor: 'gray',
      borderBottomWidth: 0.5,
    },
    icon: {
      marginRight: 5,
    },
    placeholderStyle: {
      fontSize: 16,
    },
    selectedTextStyle: {
      fontSize: 16,
    },
    iconStyle: {
      width: 20,
      height: 20,
    },
    inputSearchStyle: {
      height: 40,
      fontSize: 16,
    },
  });

*از placeholderStyle و selectedTextStyle  و inputSearchStyle برای استایل دهی استفاده کنید. (لیست کامل prop ها را اینجا ببینید)

*اگر از dropdown داخل Formik استفاده می کنید، می توانید با توابع زیر مقدار آن را دریافت کنید:

onChangeText={handleChange}
        onChange={item => {
          values["gender"] = item.value;
          

      }}
0 رای

خود react native کتابخانه ای بنام ActivityIndicator  دارد که می توانید از آن استفاده کنید. بصورت زیر اسفاده کنید:

import React from 'react';
import {ActivityIndicator, StyleSheet, View} from 'react-native';

const App = () => (
  <View style={[styles.container, styles.horizontal]}>
    <ActivityIndicator />
    <ActivityIndicator size="large" />
    <ActivityIndicator size="small" color="#0000ff" />
    <ActivityIndicator size="large" color="#00ff00" />
  </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  horizontal: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    padding: 10,
  },
});

export default App;

 

  • نفیسه افقی 1 سال قبل پاسخ داد
  • آخرین فعالیت در 1 سال قبل
0 رای
در پاسخ به: آیکون ها در react native

یکی از محبوب ترین کتابخانه ها برای استفاده از آیکون در react native ، کتابخانه react native vector icons است. اول بصورت زیر نصبش کنید:

npm install react-native-vector-icons --save

بعد کافی است تا دسته آیکون هایی که می خواهید استفاده کنید را از یک فونت خاص ایمپورت کنید (مثلا: FontAwesome) . حالا بصورت زیر می توانید از آن ها استفاده کنید:

// Example to Use React Native Vector Icons
// https://aboutreact.com/react-native-vector-icons/

// Import React
import React from 'react';

// Import required component
import {SafeAreaView, StyleSheet, Text, View} from 'react-native';

// Import vector icons
import Icon from 'react-native-vector-icons/FontAwesome';

const App = () => {
  return (
    <SafeAreaView style={{flex: 1}}>
      <View style={{flex: 1, padding: 16}}>
        <View style={styles.container}>
          <Text style={styles.heading}>
            Example to Use React Native Vector Icons
          </Text>
          <View style={styles.iconContainer}>
            <Text>
              <Icon name="rocket" size={30} color="#900" />
            </Text>
            {/* Icon Component */}
            <Icon name="rocket" size={30} color="#900" />
          </View>
          <View style={{marginTop: 16, marginBottom: 16}}>
            {/* Icon.Button Component */}
            <Icon.Button
              name="facebook"
              backgroundColor="#3b5998"
              onPress={() => alert('Login with Facebook')}>
              Login with Facebook
            </Icon.Button>
          </View>
        </View>
        <Text style={styles.footerTitle}>Vector Icons</Text>
        <Text style={styles.footerText}>www.aboutreact.com</Text>
      </View>
    </SafeAreaView>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  heading: {
    fontSize: 20,
    textAlign: 'center',
    marginBottom: 20,
  },
  iconContainer: {
    marginTop: 16,
    marginBottom: 16,
    justifyContent: 'center',
    alignItems: 'center',
    textAlign: 'center',
  },
  footerTitle: {
    fontSize: 18,
    textAlign: 'center',
    color: 'grey',
  },
  footerText: {
    fontSize: 16,
    textAlign: 'center',
    color: 'grey',
  },
});

export default App;

*به دو صورت زیر می توانید از icon ها استفاده کنید:

<Icon.Button
      name="facebook"
      backgroundColor="#3b5998"
      onPress={() => alert('Login with Facebook')}>
      Login with Facebook
</Icon.Button>

<Icon name="rocket" size={30} color="#900" />

*اگر روی گوشی های اندروید آیکونی نمایش داده نشد، این کار را بکنید: داخل فایل build.gradle در پوشه android/build ، خط زیر را به انتهای فایل اضافه کنید و مجدد بیلد بگیرید (npm run android):

apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")

*react native vector icons چندین بسته معروف از آیکن ها را ساپورت می کند. لینک آیکن ها و اسامی شان را ببینید:

 آیکن های Fontawsome

Material Icons

Ionicons

Octicons

Foundation Icons

Entypo

Zocial

Evil Icons

Simple Line Icons

*اگر از این پکیج ها استفاده می کنید باید هر کدام را جدا ایمپورت و استفاده کنید:

import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons';

// Use an icon in your component
<SimpleLineIcons name="user" size={30} color="black" />;

 

  • نفیسه افقی 1 سال قبل پاسخ داد
  • آخرین فعالیت در 1 سال قبل
0 رای

سلام دوست عزیز،

بله دقیقاً راه حل همینی هست که گفتید. یعنی باید کیف پول برای هر کاربر تعریف کنید، کاربر شارژش کنه  و اگر جایی برای رزرو خالی شد، سیستم اتومات مبلغ رو از کیف پولش برداشت کنه. البته این در صورتی هست که بخواهید پرداخت هنگام خرید بلیط انجام بشه. اگر بخواهید که کاربر برای رزرو پولی پرداخت نکنه و بر اساس اعتبارش رزرو کنه که لازم به اینکار نیست.

0 رای

برای اینکار می توانید از redux یا context استفاده کنید. redux کمی پیچیده تر است، اما می توانید از هوک useContext برای پروژه های کوچکتر استفاده کنید. برای این کار، اول یک فایل (مثلا بنام UserContext.js ) بسازید و کد زیر را در آن قرار دهید:

import React, { createContext, useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';

const UserContext = createContext();

const UserProvider = ({ children }) => {
  const [userData, setUserData] = useState({
    id: null,
    token: null,
  });

   useEffect(() => {

    async function fetchData() {

        const token = await AsyncStorage.getItem('token');
        const id = await AsyncStorage.getItem('user_id');
        

        const storedUserData = {
            id: id, // Example user ID
            token: token, // Example user token
          };
      
          setUserData(storedUserData);

      
      }

      fetchData();

  }, []);

  return (
    <UserContext.Provider value={userData}>
      {children}
    </UserContext.Provider>
  );
};

export { UserProvider, UserContext };

در این مثال، ما دو متغیری که از کاربر روی حافظه AsyncStorage ذخیره کرده بودیم را می خوانیم (id و token). شما می توانید هر متغیر با هر مقداری که می خواهید تعریف کنید.

function App(): JSX.Element {
 

  
  const Tab = createBottomTabNavigator();

  return (

    <UserProvider>

    <NavigationContainer>

<LoginNavigation></LoginNavigation>
 
    

    </NavigationContainer>

    </UserProvider>
  );
}


export default App;

حالا باید این UserProvider را قبل از اولین تگ برنامه مان ، یعنی اولین فایلی که برنامه از آنجا لود می شود ، قرار دهیم (می توانید فایل index.js یا App.js باشد)

 

بعد بصورت زیر می توانیم در همه جای پروژه (در هر کامپوننتی) از متغیرهایمان استفاده کنیم:

import { UserContext } from '../../UserContext';

onst { id, token } = useContext(UserContext);

 

  • نفیسه افقی 1 سال قبل پاسخ داد
  • آخرین فعالیت در 1 سال قبل
0 رای

می توانید از AsyncStorage برای این کار استفاده کنید. با دستور زیر آن را نصب کنید:

npm install @react-native-async-storage/async-storage

 

برای نوشتن روی AsyncStorage از کد زیر استفاده کنید:

import AsyncStorage from '@react-native-async-storage/async-storage';



//cache user token:

await AsyncStorage.setItem('token', token);

و برای خواندن از حافظه از کد زیر استفاده کنید:

const token = await AsyncStorage.getItem('token');

 

0 رای

یکی از راههایی که می توانید به api درخواست http ارسال کنید، استفاده از axios است. axios کتابخانه react است و چون react native بر پایه react نوشته شده ، می توانید از axios هم در اینجا استفاده کنید. از مثال زیر استفاده کنید:

import axios from 'axios';


axios({
        method: 'get',
        url: link,
        headers: {"Content-Type": "application/json"} 
        }).then((response) => {

            //do something with result

          
      
        })
        .catch((error) => {
            
            console.error('Error fetching data:', error);
            
          });
  • نفیسه افقی 1 سال قبل پاسخ داد
  • آخرین فعالیت در 1 سال قبل
0 رای

environment variable متغیری است که بصورت global تعریف می شود و قابل دسترسی برای همه هم نیست. بنابرین اگر کدی دارید که می خواهید درون برنامه تان بطور مرنب استفاده کنید و یا قابل دیدن برای سایرین نباشد، می توانید داخل یک environment variable قرارش دهید.

برای تعریف environment variable در react native ، ابتدا کتابخانه زیر را نصب کنید:

npm install @env

حالا داخل root پروژه یک فایل بنام env. بسازید و متغیرهایتان را با فرمت زیر تعریف کنید:

API_URL=https://api.example.com
DEBUG=true

بعد باید فایل babel.config.jsرا بصورت زیر آپدیت کنید تا آدرس فایل env. را داشته باشد:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module:react-native-dotenv',
      {
        moduleName: '@env',
        path: '.env',
        blacklist: null,
        whitelist: null,
        safe: false,
        allowUndefined: true,
      },
    ],
  ],
};

بصورت زیر هم می توانید داخل برنامه تان از environmrnt variable ها استفاده کنید:

process.env.DEBUG

*برای تعریف environment variable در react و nest.js ، لینک ها را ببینید.

  • نفیسه افقی 1 سال قبل پاسخ داد
  • آخرین فعالیت در 1 سال قبل
0 رای
در پاسخ به: Floating Botton در react native

برای این کار می توانید از کتابخانه react-native-floating-action استفاده کنید. با کد زیر نصبش کنید:

npm install react-native-floating-action 

با دستور زیر، ایمپورتش کنید:

import { FloatingAction } from 'react-native-floating-action';

و بصورت زیر استفاده کنید:

const YourComponent = () => {

  const actions = [
    {
      text: 'Option 1',
      icon: require('path-to-your-icon-1.png'),
      name: 'option1',
      position: 2,
    },
    {
      text: 'Option 2',
      icon: require('path-to-your-icon-2.png'),
      name: 'option2',
      position: 1,
    },
    // Add more options as needed
  ];

  return (
    <View style={{ flex: 1 }}>
      {/* Your main content goes here */}

      {/* Floating Action Button */}
      <FloatingAction
        actions={actions}
        onPressItem={(name) => {
          // Handle button press based on the selected option
          console.log(`Option selected: ${name}`);
          // You can navigate to different screens based on the selected option
        }}
      />

     
    </View>
  );
};

export default YourComponent;

* هر action را هم می توانید جداگانه customize کنید. این لینک را ببینید.

0 رای

اگر می خواهید فونت خودتان را در react native استفاده کنید، این مراحل را انجام دهید:

1- گذاشتن فایل فونت ها در پروژه

در قسمت root پروژه، یک فولدر بنام assets بسازید و داخل این فولدر ، یک فولدر دیگر بنام fonts بسازید و فایل فونت ها (.ttf) را در آنجا قرار دهید.

 

2- ساخت فایل react-native.config.js

در همان root پروژه، یک فایل بنام react-native.config.js بسازید و کد زیر را داخل آن قرار دهید:

module.exports = {
  project: {
    ios: {},
    android: {},
  },
  assets: ['./assets/fonts'],
};

3- لینک فولدر asset به پروژه

حالا دستور زیر را در ترمینال وارد کنید:

npx react-native-asset

حالا می توانید از فونت های سفارشی خودتان در همه جای پروژه استفاده کنید. (دقت کنید که باید دقیقا نام فایل فونت را استفاده کنید). یک نمونه از استفاده از فونت:

import {StyleSheet, Text, View} from 'react-native';
import React from 'react';
const App = () => {
  return (
    <View style={styles.container}>
      <Text style={styles.quicksandRegular}>
        This text uses a quick sand font
      </Text>
      <Text style={styles.quicksandLight}>
        This text uses a quick sand light font
      </Text>
      <Text style={styles.ralewayThin}>
        This text uses a thin italic raleway font
      </Text>
      <Text style={styles.ralewayItalic}>
        This text uses a thin italic raleway font
      </Text>
    </View>
  );
};
export default App;
const styles = StyleSheet.create({
  container: {
    backgroundColor: 'lavender',
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  quicksandLight: {
    fontFamily: 'Quicksand-Light',
    fontSize: 20,
  },
  quicksandRegular: {
    fontFamily: 'Quicksand-Regular',
    fontSize: 20,
  },
  ralewayItalic: {
    fontFamily: 'Raleway-Italic',
    fontSize: 20,
  },
  ralewayThin: {
    fontFamily: 'Raleway-ThinItalic',
    fontSize: 20,
  },
});
0 رای

برای اینکار می توانید داخل تابع functions.php از کد زیر استفاده کنید:

function custom_woocommerce_text($translated_text, $text, $domain) {
    switch ($translated_text) {
        case 'Product':
            $translated_text = 'File';
            break;
        // Add more cases for other phrases you want to customize

        // Example for changing "Add to Cart" button text:
        // case 'Add to cart':
        //     $translated_text = 'Custom Button Text';
        //     break;
    }
    return $translated_text;
}
add_filter('gettext', 'custom_woocommerce_text', 20, 3);

به جای Product و  File هر عبارتی که می خواهید را قرار دهید.

0 رای
در پاسخ به: هزینه طراحی

سلام دوست عزیز، بستگی به میزان فیچرهایی داره که میخواهید داشته باشه، برای چنین پروژه هایی باید برنامه نویسی کرد. اگر تمایل داشتید میتونم در واتساپ بیشتر راهنمایی تون کنم: 09352333881

0 رای

فرض کنید یک اپلیکیشن چت نوشتیم و می خواهیم بصورت real time پیام ها را نمایش دهیم. یعنی وقتی کاربر1 به کاربر2  پیام می فرستد، نیازی به رفرش کردن صفحه نباشد. یا مثلاً وقتی کاربر1 وارد صفحه چت شد، آنلاین بودنش به تمامی دوستانش نمایش داده شود. برای این طور کارها از مفهومی بنام websocket استفاده می کنیم.

websocket نوعی از کانکشن است. برعکس کانکشن http که بعد از ارسال داده بسته می شود، websocket کانکشنی است که تا زمانیکه دو طرف بخواهند باز می ماند و می توان بینشان داده رد و بدل کرد. کانکشن websocket به جای http با ws شروع می شود.

حالا چطور از websocket استفاده کنیم؟

websocket را باید برای server و client جدا پیاده سازی کنیم.

اول لازم است تا روی سرور یک gateway باز کنیم. gateway سروری است که روی یک پورت بالا می آید و همیشه بالا است. client ها با websocket به آن connect و disconnect می شوند، message ارسال می کنند و به تمامی message هایی که ارسال می شود گوش می دهند. (gateway  هم می تواند به تمامی client هایی که وصل هستند، یک message را ارسال کند)

مثلاً وقتی کاربر1 وارد چت می شود، با یک websocket به gateway وصل می شود. حالا ما می توانیم به تمامی کاربرانی که داخل آن چت روم هستند آنلاین شدن کاربر1 را اطلاع دهیم. یا اگر کاربر1 پیامی به کاربر2 ارسال کند، پیام را بلافاصله به کاربر2 ارسال کنیم. (چون کاربر2 هم به gateway متصل است)

برای مثال، ما اینجا در سمت client از react استفاده می کنیم و در سمت سرور از nest.js

 

سمت سرور

یک پروژه nest.js بسازید. بهتر است پروژه websocket را از پروژه اصلی back-end تان جدا کنید. (تا به تداخل depency ها برنخورید. می توانید هر کدام را هم روی یک پورت جدا بالا بیاورید)

کتابخانه های زیر را نصب کنید:

npm install socket.io @nestjs/websockets

داخل فولدر src پروژه یک فولدر بنام websocket بسازید و دو فایل با نامهای websocket.module.ts و websocket.service.ts بسازید.

فایل یک ماژول است که باید فایل را به عنوان provider برایش تعریف کنید:

// websocket.module.ts
import { Module } from '@nestjs/common';
import { WebSocketService } from './websocket.service'; // Import your WebSocket gateway


@Module({
  providers: [WebSocketService], // Add your WebSocket gateway here
})
export class WebSocketModule {}

باید داخل فایل app.module.ts هم ماژولی که ساختید را ایمپورت کنید:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { WebSocketModule } from './websocket/websocket.module';

@Module({
  imports: [WebSocketModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

فایل websocket.service.ts ، فایل اصلی است که وطیفه اش ساختن gateway است:

import { ConnectedSocket, MessageBody, OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage, WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
import { Server } from 'socket.io';
import { Socket } from 'socket.io';
import { Logger } from '@nestjs/common';


@WebSocketGateway()
export class WebSocketService implements OnGatewayConnection, OnGatewayDisconnect {
  @WebSocketServer()
  server: Server;
  private readonly logger = new Logger(WebSocketService.name);


  constructor() {
    console.log('WebSocketService initialized'); 
  }



  
  afterInit(server: Server) {
    console.log('Initialized');
  }

  

  handleConnection(client: Socket) {
    console.log(`Client connected: ${client.id}`);
    // Handle connection event
  }
  
  handleDisconnect(client: Socket) {
    console.log(`Client disconnected: ${client.id}`);
    // Handle disconnection event
  }
  
  @SubscribeMessage('chat_message')
  handleMessage(@MessageBody() data: string, @ConnectedSocket() client: Socket) {
    console.log(`Received message from ${client.id}: ${data}`);
    // Handle received message
    this.server.emit('chat_message', data); // Broadcast the message to all connected clients
  }



  @SubscribeMessage('joinChatRoom')
  handlejoinChatRoom(@MessageBody() data: string, @ConnectedSocket() client: Socket) {
    console.log(`joinChatRoom with id : ${data}`);

    this.server.emit('joinChatRoom', data);
  }

  @SubscribeMessage('leftChatRoom')
  handleLeftChatRoom(@MessageBody() data: string, @ConnectedSocket() client: Socket) {

    this.server.emit('leftChatRoom', data); 
  }


  
  
@SubscribeMessage('events')
handleEvent(@MessageBody() data: string): string {
  return data;
}


  
}

*SubscribeMessage('joinChatRoom') مشخص می کند پیامی که ارسال و دریافت می شود با چه آیدی است (joinChatRoom) . در سمت فرانت هم باید با همین آیدی پیامتان را ارسال و دریافت کنید.

* this.server.emit('leftChatRoom', data); پیام را به تمامی client هایی که به این gateway هستند ارسال می کند.

سمت client

سمت فرانت ، مثلا جایی که کاربر صفحه چت را باز می کند، یک useEffect بنویسید که اتصال websocket را برقرار کند و به event ها (یا همان پیامها) که می آید گوش دهد. با تابع emit هم می توانید به gateway داده ارسال کنید:

*یادتان باشد که وقتی صفحه چت بسته شد، حتما socket را ببندید.

useEffect( () => {
      
      const initializeSocket = async () =>
      {
        
        
        const socket = io('ws://localhost:5000', { transports: ['websocket'] });


        socket.on('chat_message', async (chat_message) => {

          console.log("chat_message",chat_message);
      
        });

      
        socket.on('joinChatRoom', async (joinChatRoom) => {

          console.log("socket joinChatRoom",joinChatRoom);
        });

        socket.on('leftChatRoom', async (leftChatRoom) => {
    
          console.log("socket leftChatRoom",leftChatRoom);
        });


        socket.on('connect', () => {
          console.log('Connected to WebSocket');
        });
        
        socket.on('disconnect', () => {
          console.log('Disconnected from WebSocket');
          
        });


    
      }

      
      return () => {

        socket?.emit("leftChatRoom",{user_id:onlineUser._id})
        socket?.disconnect(); // Disconnect when the component unmounts
      };

      
    }, [messageDialog]);

* ws://localhost:5000آدرس پورت سرور است که gateway را روی آن بالا آوردید. اگر از https استفاده می کنید به جای ws از wss استفاده کنید.

*هر جایی از برنامه ، مثلا وقتی کاربر پیامی جدید ارسال کرد، می توانید به gateway هم ارسال کنید:

socket.emit('chat_message', data );
  • نفیسه افقی 2 سال قبل پاسخ داد
  • آخرین فعالیت در 2 سال قبل
0 رای

فرض کنیم یک پایگاه داده با داده های زیاد داریم و کاربر می خواهد روی آن ها سرچ بزند. چند راه مختلف برای این کار وجود دارد:

  • یکی از راههای پیاده سازی سرچ این است که کل داده ها را از back-end بگیریم و بعد بنا به کاراکترهایی که کاربر در input وارد می کند، داده موردنظر را نشانش بدهیم. این روش صد در صد بدترین نوع پیاده سازی سرچ است. چون اگر داده ها زیاد باشد، حافظه را پر خواهد کرد. و لزومی هم به داشتن داده های غیرمرتبط با سرچ نیست.
  • راه دیگر این است که به ازای هر کاراکتری که کاربر وارد می کند، یک درخواست به back-end بدهیم تا تنها داده هایی که آن کاراکتر را دارند به ما برگرداند. این روش هم بهینه نیست. چون اگر قرار باشد به ازای هر کاراکتری که کاربر وارد می کند یک درخواست به دیتابیس بدهیم ، بار زیادی را روی سرور می اندازیم و قطعا برنامه کند می شود.
  • بهینه ترین راهی که بیشتر شبکه های اجتماعی هم از آن استفاده می کنند این است که یک مدت زمان خاصی بعد از تمام شدن تایپ کاربر صبر کنیم و بعد محتوایی که تا به اینجا تایپ کرده را در درخواستمان به back-end بدهیم تا با آن سرچ کند.

حالا چطور روش سوم را در react پیاده سازی کنیم؟

اول یک متغیر برای نگهداری محتوایی که کاربر برای سرچ وارد می کند (searchValue) می سازیم:

const [searchValue,setSearchValue] = useState("");

حالا تگ input که کاربر داخل آن سرچ می کند را تعریف می کنیم (من از prime react InputText استفاده کردم):

import { InputText } from "primereact/inputtext"; 

.
.
.
<InputText
              className="search-box"
              placeholder="اینجا جستجو کنید ..."
              value={searchValue}
              onChange={handleSearch}
            />

تابع handleSearch ، محتوای وارد شده را داخل searchValue قرار می دهد، اما دستور سرچ را نمی دهد:

const handleSearch = (event) => {
    const { value } = event.target;
    
    setSearchValue(value);
  
  };

حالا یک useEffect تعریف می کنیم که با مقداری تاخیر (در اینجا 500 میلی ثانیه) ، دستور سرچ با searchValue را می دهد.

// Create a debounced version of the API request
  useEffect(() => {
    
    const delayedApiRequest = setTimeout(() => {
      if (searchValue) {
        fetchPosts(searchValue);
      }
    }, 500);

*در اینصورت موقعی که کاربر در حال تایپ کردن است ما سرچی انجام نمی دهیم و تنها بعد از اینکه 500 میلی ثانیه از تمام شدن تایپش گذشت این کار را انجام می دهیم.

*تابع fetchPosts(searchValue ، کار fetch کردن داده ها را برای سرچ انجام می دهد. اگر از mongo برای دیتابیس استفاده می کنید، می توانید این لینک را برای پیاده سازی سرچ ببینید.

  • نفیسه افقی 2 سال قبل پاسخ داد
  • آخرین فعالیت در 2 سال قبل
0 رای

فرض کنید سرویس های مختلفی (GET,POST,DELETE,PATCH,UPDATE) برای back-end نوشتیم، اگر آدرس و پورت back دست هر شخصی بیفتد ، می تواند سرویس های شما را فراخوانی کند (مثلاً پستی یا همه پست ها را حذف کند، آپدیت کند و …)

برای جلوگیری از دسترسی افراد احراز هویت نشده باید چکار کنیم؟

برای این کار باید برای هر سرویس Guard تعریف کنیم. با گذاشتن decorator ای بنام UseGuards@ بالای هر تایع controller می توانیم کاری کنیم که آن تابع تنها پس از احراز هویت اجرا شود. برای احراز هویت هم الگوریتم های مختلفی وجود دارد که ما از یکی از ممعروفترین آن ها یعنی JWT استفاده می کنیم. نام الگوریتمی که استفاده می کنیم باید کنار decorator نوشته شود. یعنی تابع deleteای که داخل controller نوشتیم ، به این صورت در می آید:

@UseGuards(JwtAuthGuard)
@Delete(":_id")
  async deletePage(
    @Param("_id") _id: string) {
    return await this.pagesService.deletePage(_id);
  }

JWT چطور احراز هویت می کند؟

jwt مخفف json web token است و بدین صورت عمل می کند که وقتی کاربر احراز هویت شد و لاگین کرد، یک توکن با محتوایی که می خواهیم (مثلا شامل id و role کاربر، یا هر داده ای که می خواهیم) می سازیم ، رمزنگاری می کنیم و به front-end می فرستیم. قسمت front-end ، این توکن رمزنگاری شده را در local storage  ذخیره می کند و هر زمان خواست http request ای به back-end بفرستد، این توکن را داخل header قرار می دهد و می فرستد. back-end هم این توکن را می گیرد، باز می کند و اگر درست بود، درخواست احراز هویت می شود و تابع مذکور اجرا می شود. در اینصورت تنها کسانی می توانند تابع ما را اجرا کنند که توکن داشته باشند.

*دقت کنید که می توانیم برای توکن تاریخ انقضا تعریف کنیم. (مثلاً اگر کاربر داخل کافی نت لاگین کرده و توکن آنجا ذخیره شده باشد، ممکن است شخص دیگه ای به توکن دسترسی پیدا کن)

برای استفاده از jwt ، لازم است تا کتابخانه های زیر را نصب کنید:

npm install @nestjs/jwt
npm install passport-jwt
npm install jsonwebtoken

 

چطور بعد از لاگین کاربر، توکن بسازیم و ارسال کنیم؟

در تابعی که برای لاگین کاربر نوشته اید، jsonwebtoken را ایمپورت کنید:

import * as jwt from 'jsonwebtoken';

و به صورت زیر یک توکن بسازید و امضایش کنید:

async tokenGenerator(payload:AuthPayload)
      {
        return jwt.sign(payload,process.env.ACCESS_JWT_SECRET);
      }

*AuthPayload مدلی است که برای توکن تعریف کرده ایم. شما هر داده ای از کاربر را می توانید به عنوان توکن تعریف کنید. مثلا ما AuthPayload را در فولدری بنام auth و بدین صورت تعریف کرده ایم:

export class AuthPayload
{
    user_id:string;
    role:string;
    
}

*payload به معنای توکنی است که رمزش باز شده.

*اکیدا توصیه می شود که کلیدی که توکن به وسیله آن رمزنگاری شده و باز می شود را در فایل env. و به عنوان environment variable ذخیره کنید.

*وقتی کاربر با موفقیت لاگین شد، باید این توکن را به فرانت ارسال کنیم و فرانت هم باید آن ها در local storage ذخیره کند.

 

چطور JwtAuthGuard را بسازیم؟

فولدری بنام auth بسازیم و داخل آن باید دو فایل اصلی برای guard و strategy داشته باشید.

فایل jwt-auth-guard.ts را بدین صورت تعریف کنید:

import { Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt')
{

}

فایل jwt-strategy.ts را بدین صورت تعریف کنید:

import {PassportStrategy} from "@nestjs/passport";
import {ExtractJwt, Strategy} from "passport-jwt";
import { Injectable} from "@nestjs/common";


@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
    constructor() {

        super({
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            ignoreExpiration: false,
            secretOrKey: process.env.ACCESS_JWT_SECRET,
        })
    }

    async validate(payload: any) {
        
        return {user_id: payload.user_id, role: payload.role}
    }

 
}

حالا کافی است تا در فایل کنترلری که می خواهیم از guard استفاده کنیم، JwtAuthGuard را ایمپورت کنیم:

import { JwtAuthGuard } from "src/auth/jwt-auth-guard";

و بالای تابع موردنظرمان، از decorator زیر استفاده کنیم:

 @UseGuards(JwtAuthGuard)

 

*بهتر است auth را بصورت ماژول در آورید (حتی می توانید تابع تولید کننده توکن tokenGenerator ، را داخل AuthService قرار دهید):

import { Module } from "@nestjs/common"
import { PassportModule } from "@nestjs/passport"
import { UsersModule } from "src/users/users.module"
import { AuthService } from "./auth.service"


@Module({
  imports: [PassportModule.register({ session: true })],
  providers: [AuthService],
})
export class AuthModule {}

*دقت کنید که باید داخل فایل app.module هم jwt را ایمپورت کرده و به عنوان ماژل اضافه کنید:

import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './auth/strategy/jwt-strategy';




@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({secret: process.env.ACCESS_JWT_SECRET}), 
    AuthModule],

  controllers: [AppController],
  providers: [AppService,JwtStrategy],
})

export class AppModule {}

چطور در فرانت ، توکن را داخل http request قرار دهیم و ارسال کنیم؟

به صورت زیر می توانید header درخواستتان را بسازید (توکن را از local storage بگیرید و داخل آن قرار دهید):

const token = JSON.parse(localStorage.getItem('Token'));
const config = {  headers: {"Content-Type": "application/json",Authorization: `Bearer ${token}`} }

حالا header را داخل درخواست axios قرار دهید:

axios.patch("BACK_END_ADRESS", data, config);
  • نفیسه افقی 2 سال قبل پاسخ داد
  • آخرین فعالیت در 2 سال قبل
0 رای

با روش symmetric encryption می توانیم این کار را انجام دهیم. بدین صورت که پیامی که می خواهیم ارسال شود را با کمک یک SECRET_KEY در فرانت رمزنگاری می کنیم، داده رمزنگاری شده را ارسال می کنیم و بعد در بک ، به کمک همان SECRET_KEY بازش می کنیم.

برای رمزنگاری داده هم می توانیم از الگوریتم AES (Advanced Encryption Standard) استفاده کنیم. برای این کار، کتابخانه زیر را نصب کنید:

npm install crypto-js

حالا از آن برای رمزنگاری داده تان استفاده کنید:

import React, { useState } from 'react';
import CryptoJS from 'crypto-js';

function App() {
  const [message, setMessage] = useState('');
  const secretKey = 'your-secret-key';

  const encryptData = () => {
    const encrypted = CryptoJS.AES.encrypt(message, secretKey).toString();
    // Send 'encrypted' to the back end
    console.log('Encrypted Data:', encrypted);
  };

  return (
    <div>
      <input
        type="text"
        value={message}
        onChange={(e) => setMessage(e.target.value)}
      />
      <button onClick={encryptData}>Encrypt and Send</button>
    </div>
  );
}

export default App;

*تابع encryptData کار رمزنگاری را انجام می دهد.

در قسمت بک اپلیکیشن بصورت زیر داده رمزنگاری شده را دریافت کنید:

import { Controller, Post, Body } from '@nestjs/common';
import * as CryptoJS from 'crypto-js';

@Controller('data')
export class DataController {
  private secretKey = 'your-secret-key';

  @Post('decrypt')
  decryptData(@Body() encryptedData: string): string {
    const bytes = CryptoJS.AES.decrypt(encryptedData, this.secretKey);
    const decryptedMessage = bytes.toString(CryptoJS.enc.Utf8);
    return decryptedMessage;
  }
}

*نکته خیلی مهم: برای امنیت بالاتر و جلوگیری از افشای SECRET_KEY ، بهتر است آن را در فایل env. و به عنوان environment variable ذخیره کنید.

  • نفیسه افقی 2 سال قبل پاسخ داد
  • آخرین فعالیت در 2 سال قبل
0 رای

متغیرهایی وجود دارند که لازم داریم که آن ها را بصورت کلی (global) و در یک فایل تعریف کنیم تا در هر فایلی بتوانیم از آنها استفاده کنیم. به اینطور متغیرها environment variables می گوییم و بطور خاصی باید تعریف و استفاده شوند.

1- nest.js بصورت پیشفرض فایل حاوی متغیرهای environment variables را لود نمی کند ، برای این کار باید ابتدا پکیج زیر را نصب کنید:

npm install dotenv

2- حالا در فایل main.ts باید بگویید که متغیرها را لود کند:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as dotenv from 'dotenv'; // Import dotenv

async function bootstrap() {
  dotenv.config(); // Load environment variables from .env file
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}

bootstrap();

3- در پروژه nest.js باید فایلی بنام env. را حتماً در فولدر اصلی پروژه یعنی root بسازید و بصورت زیر متغیرتان را تعریف کنید:

ACCESS_JWT_SECRET=your_secret_here

4- حالا در هر قسمت از برنامه که خواستید ، بصورت زیر می توانید از آن استفاده کنید:

const secret = process.env.ACCESS_JWT_SECRET;
  • نفیسه افقی 2 سال قبل پاسخ داد
  • آخرین فعالیت در 2 سال قبل
0 رای

فرض کنید در یک صفحه html قرار داریم و می خواهیم با کلیک بر روی یک باتن، به یک المان خاص scroll کنیم. برای این کار می توانیم از تابع scrollIntoView استفاده کنیم.

کافی است تا برای المانی که می خواهیم نهایتاً به آن اسکرول کنیم یک رفرنس یا ref تعریف کنیم و بعد در تابع کلیک باتن مان، تابع scrollIntoView را روی رفرنس آن المان فراخوانی کنیم:

import { useRef } from 'react';

export default function App() {
  const ref = useRef(null);

  const handleClick = () => {
    ref.current?.scrollIntoView({ behavior: 'smooth' });
  };

  return (
    <div>
      <button onClick={handleClick}>Scroll to element</button>

      <div style={{ height: '150rem' }} />

      <div ref={ref} style={{ backgroundColor: 'lightblue' }}>
        Coding Beauty
      </div>

      <div style={{ height: '150rem' }} />
    </div>
  );
}
نمایش 21 - 40 از 310 نتیجه